Задержите эффект использования до тех пор, пока useSelector не получит данные из хранилища Redux в React Native

#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 . У вас может быть больше одного.