#javascript #reactjs #react-native #react-redux
Вопрос:
У меня есть функциональный компонент реагирования Tasks_1, и изначально я хочу получить идентификатор пользователя из хранилища redux, который успешно работает.
После этого я хочу использовать идентификатор пользователя в useEffect, который я извлек из хранилища redux, для получения данных из серверной части.
Когда запускается useEffect, он говорит, что из идентификатора состояния извлечена пустая строка. Как я могу запустить useEffect после того, как состояние «идентификатор» задано в useState, извлекая его из хранилища?
function Tasks_1 () {
const [id, setId] = useState('');
const userId = useSelector((state) => state.id);
const [tasks, setTasks] = useState([]);
useEffect(() => {
setId(userId);
if (id !== '') {
db.collection('users').doc(id).collection('tasks').onSnapshot((snapshot)=>{
const tempTasks = [];
snapshot.forEach(
doc => {
tempTasks.push(doc.data());
}
)
setTasks(tempTasks);
});
}
}),[id];
return (
...
)
}
Комментарии:
1. Не совсем понимаю проблему — Что делает ваш нынешний подход недостаточным? Я имею в виду, что у вас есть оператор if
if (id !== '')
, который гарантирует, что вы не будете вызывать базу данных, если идентификатор не был установлен.2. Вы забыли добавить
userId
вuseEffect
зависимости. Он будет обновлен при получении значения.3. Да, по какой-то причине я бы либо получил ошибки бесконечного цикла, либо ошибку «путь пуст» при создании моментального снимка с заднего конца. Теперь я также вижу, что я не использовал идентификатор пользователя в зависимостях, что было концепцией, с которой я не был так хорошо знаком до сих пор.
Ответ №1:
Вы можете получить бесконечный цикл, если вы заставите это работать так, как у вас есть. Обновление id
setId
с помощью приведет к повторному отображению, и эффект использования будет вызван снова, так как вы изменили id
и так далее….
Я верю, что это сработает:
const [id, setId] = useState('');
const userId = useSelector((state) => state.id);
const [tasks, setTasks] = useState([]);
useEffect(() => {
// this will make sure you only set id when userId
// is a valid value, and it won't reset it every
// serenader
if(userId!=='' amp;amp; id !== userId)
setId(userId);
if (id !== '') {
db.collection('users').doc(id).collection('tasks').onSnapshot((snapshot)=>{
const tempTasks = [];
snapshot.forEach(
doc => {
tempTasks.push(doc.data());
}
)
setTasks(tempTasks);
});
}
}, [id, userId]);
и вам придется добавить userId
в массив зависимости.
Комментарии:
1. Да, иногда я получал ошибку бесконечного цикла, поэтому я не был уверен, как это структурировать так, чтобы данные с бэкэнда были получены после. позвольте мне попробовать то, что вы предложили!
2. в этом случае будет ли у эффекта использования причина продолжать проверять наличие изменений в идентификаторе пользователя? так же, как тест для удовольствия, im consol.log(идентификатор пользователя) и is продолжает регистрировать его с интервалами почти, но это сработало для меня!
3. @MattLaszcz useefect вспоминается каждый раз, когда либо
id
обновляется, либоuserId
обновляется. Вы определенно добьетесь того, чтобы это произошло, по крайней мере, в 3 раза. После первоначальной отрисовки, 2d , когда вы получите обновленное значениеuserId
, и в-третьих, потому что выsetId
с новымuserId
вызываете еще один повторный вызов. После этого он должен вызываться только в том случае, если эти значения изменяются внешне.4. хорошо, возможно, в моем коде есть что-то еще, что мне нужно отладить, что приводит к обновлению идентификатора и вызывает повторную отрисовку, которую я вижу тогда. Я поищу его.
5. попробуйте сделать это, чтобы проверить, не обновляется ли он
userId
более одного раза.useEffect(()=> console.log('here'),[userId]);
добавьте его в дополнение к тому, что вы в курсеuseEffect
. У вас может быть больше одного.