#javascript #reactjs #mongodb #meteor
#javascript #reactjs #mongodb #meteor
Вопрос:
Я получаю несколько возвращаемых значений для запроса Mongo.collection.findOne по идентификатору в Meteor JS и React. Я думаю, это связано с тем фактом, что это повторный рендеринг, я пытался использовать useEffect, но он работает не так, как я его реализовал, то есть просто оборачивает ведущую переменную в 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;
Есть три повторных запроса, и это результат
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
Заранее спасибо
Комментарии:
1. Похоже на типичную подписку. До завершения лидов не определено, после завершения документ доступен на клиенте. Можете ли вы добавить свой код подписки и публикации, top?
2. о, я еще не добавил sub / pub, я следил за учебным пособием meteor для приложения react todo, но менял его по ходу. Должен ли я тогда выполнить часть pub? Я использую пакет autopublish для прототипирования, так что разве он не должен работать правильно
Ответ №1:
Как JanK. как уже указывалось, вы захотите выполнить подписку вручную. Когда вы это сделаете, вы получите .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>;
}
Ответ №2:
Поведение, которое вы видите, является нормальным для подписок Meteor
https://dweldon .silvrback.com/common-mistakes
Subscribe работает как садовый шланг — вы включаете его, и через некоторое время все выходит с другого конца. Активация подписки не блокирует выполнение браузера, поэтому немедленный поиск в коллекции не вернет никаких данных.
Это немного раздражает код, потому что ваш компонент не должен допускать никаких данных (в первый раз). Это означает, что любые правила 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)