Meteor, useTracker mongo.collection.findOne returns undefined, 然后正确取值
Meteor, useTracker mongo.collection.findOne returns undefined, then correct value
我在 Meteor JS 和 React 中通过 ID 获得 return 查询的多个 return 值。我认为这与重新渲染有关,我曾尝试使用 useEffect 但它无法按照我实现它的方式工作,它只是将 lead 变量包装在 useEffect 中。
这是我的代码
import React, { useState, useEffect } from "react";
import Dasboard from "./Dashboard";
import { Container } from "../styles/Main";
import { LeadsCollection } from "../../api/LeadsCollection";
import { Lead } from "../leads/Lead";
import { useTracker } from "meteor/react-meteor-data";
const Walkin = ({ params }) => {
const [email, setEmail] = useState("");
const [testIdA, setTestId] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
};
const lead = useTracker(() => LeadsCollection.findOne({ _id: params._id }));
console.log(lead);
console.log(params._id);
const deleteLead = ({ _id }) => LeadsCollection.remove(_id);
return (
<Container>
<Dasboard />
<main className="split">
<div>
<h1>Add a lead below</h1>
<form className="lead-form" onSubmit={handleSubmit}>
{/* <input
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Type to add new lead"
/> */}
<button type="submit">Edit Lead</button>
</form>
</div>
<p>{params._id}</p>
{/* <Lead key={params._id} lead={lead} onDeleteClick={deleteLead} /> */}
</main>
</Container>
);
};
export default Walkin;
有3次重新渲染,这是结果
undefined
Walkin.jsx:20 sLg7dk3KdS7boZuHB
Walkin.jsx:18 undefined
Walkin.jsx:20 sLg7dk3KdS7boZuHB
Walkin.jsx:18 {_id: "sLg7dk3KdS7boZuHB", email: "fasfdas", createdAt: Wed Nov 11 2020 21:40:39 GMT-0700 (Mountain Standard Time)}
Walkin.jsx:20 sLg7dk3KdS7boZuHB
提前致谢
作为简克。已经指出,您需要手动进行订阅。当你这样做时,你会得到一个 .ready
函数,你可以用它来判断客户端上的数据是否可用,并在此之前显示一个加载页面。
这是一个典型的实践示例:
const Walkin = ({ params }) => {
const {lead, ready} = useTracker(() => {
const subscription = Meteor.subscribe('leads', params._id);
return {
lead: LeadsCollection.findOne({ _id: params._id })),
ready: subscription.ready()
};
}, [params._id]);
if (!ready) {
return <div>loading</div>
}
return <div>
The actual page where lead is used.
</div>;
}
您看到的行为对于 Meteor 订阅是正常的
https://dweldon.silvrback.com/common-mistakes
Subscribe works like a garden hose - you turn it on and, after a
while, things come out the other end. Activating the subscription does
not block execution of the browser, therefore an immediate find on the
collection won't return any data.
这对编码来说有点烦人,因为您的组件需要允许没有数据(第一次)。这意味着您组件上的任何 propTypes 规则都将失败。我使用的技术是在数据和组件本身之间插入一个“加载”组件。
下面是容器组件的代码。
const Loading = (props) => {
if (props.loading) return <div>Loading...</div>
return <Launch {...props}></Launch>
}
const Launcher = withTracker((props) => {
const subsHandle = Meteor.subscribe('list.workflows')
const methods = { launchJob }
return {
workflows: Workflows.find({}).fetch(),
methods,
loading: !subsHandle.ready(),
}
})(Loading)
export default Launcher
容器 (<Launcher>
) 负责获取数据并进行任何 Meteor
交互,例如方法调用。 <Launch>
组件只负责渲染。它可以有严格的 propType 规则来帮助诊断丢失的数据,也可以由 Storybook 和任何测试工具呈现(因为它没有流星依赖)。这也使组件更便携(即它可以在非 Meteor 项目中使用)
我在 Meteor JS 和 React 中通过 ID 获得 return 查询的多个 return 值。我认为这与重新渲染有关,我曾尝试使用 useEffect 但它无法按照我实现它的方式工作,它只是将 lead 变量包装在 useEffect 中。
这是我的代码
import React, { useState, useEffect } from "react";
import Dasboard from "./Dashboard";
import { Container } from "../styles/Main";
import { LeadsCollection } from "../../api/LeadsCollection";
import { Lead } from "../leads/Lead";
import { useTracker } from "meteor/react-meteor-data";
const Walkin = ({ params }) => {
const [email, setEmail] = useState("");
const [testIdA, setTestId] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
};
const lead = useTracker(() => LeadsCollection.findOne({ _id: params._id }));
console.log(lead);
console.log(params._id);
const deleteLead = ({ _id }) => LeadsCollection.remove(_id);
return (
<Container>
<Dasboard />
<main className="split">
<div>
<h1>Add a lead below</h1>
<form className="lead-form" onSubmit={handleSubmit}>
{/* <input
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Type to add new lead"
/> */}
<button type="submit">Edit Lead</button>
</form>
</div>
<p>{params._id}</p>
{/* <Lead key={params._id} lead={lead} onDeleteClick={deleteLead} /> */}
</main>
</Container>
);
};
export default Walkin;
有3次重新渲染,这是结果
undefined
Walkin.jsx:20 sLg7dk3KdS7boZuHB
Walkin.jsx:18 undefined
Walkin.jsx:20 sLg7dk3KdS7boZuHB
Walkin.jsx:18 {_id: "sLg7dk3KdS7boZuHB", email: "fasfdas", createdAt: Wed Nov 11 2020 21:40:39 GMT-0700 (Mountain Standard Time)}
Walkin.jsx:20 sLg7dk3KdS7boZuHB
提前致谢
作为简克。已经指出,您需要手动进行订阅。当你这样做时,你会得到一个 .ready
函数,你可以用它来判断客户端上的数据是否可用,并在此之前显示一个加载页面。
这是一个典型的实践示例:
const Walkin = ({ params }) => {
const {lead, ready} = useTracker(() => {
const subscription = Meteor.subscribe('leads', params._id);
return {
lead: LeadsCollection.findOne({ _id: params._id })),
ready: subscription.ready()
};
}, [params._id]);
if (!ready) {
return <div>loading</div>
}
return <div>
The actual page where lead is used.
</div>;
}
您看到的行为对于 Meteor 订阅是正常的
https://dweldon.silvrback.com/common-mistakes
Subscribe works like a garden hose - you turn it on and, after a while, things come out the other end. Activating the subscription does not block execution of the browser, therefore an immediate find on the collection won't return any data.
这对编码来说有点烦人,因为您的组件需要允许没有数据(第一次)。这意味着您组件上的任何 propTypes 规则都将失败。我使用的技术是在数据和组件本身之间插入一个“加载”组件。
下面是容器组件的代码。
const Loading = (props) => {
if (props.loading) return <div>Loading...</div>
return <Launch {...props}></Launch>
}
const Launcher = withTracker((props) => {
const subsHandle = Meteor.subscribe('list.workflows')
const methods = { launchJob }
return {
workflows: Workflows.find({}).fetch(),
methods,
loading: !subsHandle.ready(),
}
})(Loading)
export default Launcher
容器 (<Launcher>
) 负责获取数据并进行任何 Meteor
交互,例如方法调用。 <Launch>
组件只负责渲染。它可以有严格的 propType 规则来帮助诊断丢失的数据,也可以由 Storybook 和任何测试工具呈现(因为它没有流星依赖)。这也使组件更便携(即它可以在非 Meteor 项目中使用)