Реагируйте setState ловушки useState, успешно обновляя состояние, но не повторно обрабатывая компонент - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь обновить свое старое приложение Todo List React, чтобы оно использовало хуки, и не могу понять это на всю жизнь. setTodos успешно обновляет состояние при загрузке, как показано в инструментах разработчика React, но компонент не выполняет повторную визуализацию, и на экране отображается пустой список задач. Только когда я добавляю Todo в список, он перерисовывается, и все задачи отображаются. Вот что у меня есть:

const App = () => {

// Todos are the only state in App
const [ todos, setTodos ] = useState([]);

// Fetches Todos from Firestore database on load
useEffect(() => {
    const initialState = [];
    dbTodos.get().then((snapshot) => {
        snapshot.forEach((doc) => {
            const currentTodo = doc.data();
            currentTodo['id'] = doc.id;
            initialState.push(currentTodo);
        });
    });
    setTodos(initialState);
    // eslint-disable-next-line
}, []);

// Add Todo
const addTodo = (title) => {
    const newTodo = {
        title     : title,
        completed : false
    };
    dbTodos.add(newTodo).then((doc) => {
        newTodo['id'] = doc.id;
        setTodos([ ...todos, newTodo ]);
    });
};

Вот код, который я использовал перед реализацией хуков:

componentDidMount() {
    dbTodos.get().then((snapshot) => {
        snapshot.forEach((doc) => {
            const currentTodo = doc.data();
            currentTodo['id'] = doc.id;
            setState({ ...state, todos: [ ...state.todos, currentTodo ] });
        });
    });
};

Ответы [ 3 ]

1 голос
/ 31 марта 2020

Вы должны переместить setTodos в UseEffect

useEffect(() => {
    dbTodos.get().then((snapshot) => {
        const initialState = [];    // Also this you can move here

        snapshot.forEach((doc) => {
            const currentTodo = doc.data();
            currentTodo['id'] = doc.id;
            initialState.push(currentTodo);
        });

        setTodos(initialState);   /// here
    });
}, []);
0 голосов
/ 31 марта 2020

При использовании эффекта вы создаете пустой массив. Сделать запрос. установить пустой массив в состояние. Когда запрос был выполнен, вы вносите изменения в массив по ссылке. Следовательно, вы видите свой массив в инструменте dev и реагируете, что он не отображает ваш компонент.

const App = () => {

// Todos are the only state in App
const [ todos, setTodos ] = useState([]);

// Fetches Todos from Firestore database on load
useEffect(() => {
    dbTodos.get().then((snapshot) => {
        setTodos(snapshot.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        })));
    });
}, []);

// Add Todo
const addTodo = (title) => {
    const newTodo = {
        title     : title,
        completed : false
    };
    dbTodos.add(newTodo).then((doc) => {
        newTodo['id'] = doc.id;
        setTodos([ ...todos, newTodo ]);
    });
};
0 голосов
/ 31 марта 2020

Когда вы используете setState в useEffect, вы должны добавить setState в зависимость. Вместо этого используйте другую функцию стрелки и вызовите ее из useEffect.

используйте код ниже

const App = () => {

// Todos are the only state in App
const [ todos, setTodos ] = useState([]);

// Fetches Todos from Firestore database on load
const fetchData = () => {
    const initialState = [];
    dbTodos.get().then((snapshot) => {
        snapshot.forEach((doc) => {
            const currentTodo = doc.data();
            currentTodo['id'] = doc.id;
            initialState.push(currentTodo);
        });
    });
    setTodos(initialState);
}

useEffect(() => {
  fetchData();
}, []);

// Add Todo
const addTodo = (title) => {
    const newTodo = {
        title     : title,
        completed : false
    };
    dbTodos.add(newTodo).then((doc) => {
        newTodo['id'] = doc.id;
        setTodos([ ...todos, newTodo ]);
    });
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...