значение состояния всегда по умолчанию. Реакция js 16.12.0 - PullRequest
1 голос
/ 03 февраля 2020

У меня есть два useEffect-s. Один используется для извлечения данных из API и сохранения его в состоянии, а второй вызывается только один раз, и начинается прослушивание события websocket. В обработчике событий websocket я регистрирую извлеченные данные, но они всегда имеют значение по умолчанию. Несмотря на то, что выборка данных завершается успешно, а список рисуется в пользовательском интерфейсе, значение списка всегда пусто - [].

const [list, setList] = useState([]);

useEffect(() => {
   axios.get("https://sample.api.com/get/list")
       .then(res => {
           setList(res.data);
       });
}, [window.location.pathname.split('/')[2]]);

useEffect(() => {
   webSocket.on('messageRecieved', (message) => {
        console.log(list);
    }); 
}, []);

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Ваш второй эффект ссылается на начальное значение списка (пустой массив) из-за закрытия. Вот почему useEffect должно ссылаться на все свои зависимости во втором аргументе.

Но в этом случае, когда вы не хотите подписываться на событие webSocket при каждом обновлении списка, вы можете использовать ссылки React. в списке.

const listValue = useRef([]);
const [list, setList] = useState(listValue.current);

При установке значения:

res => {
    listValue.current = res.data
    setList(listValue.current);
}

И при получении списка за одноразовое использование. Эффект:

useEffect(() => {
    webSocket.on('messageRecieved', (message) => {
       console.log(listValue.current);
    }); 
}, []);
0 голосов
/ 03 февраля 2020

попробуйте изменить

.then(res => {

на

.then((res) => {

Уточнил бы, добавили ли вы журналы консоли для каждой ловушки или сказали, что в них заданы значения:

useEffect(() => {
   axios.get("https://sample.api.com/get/list")
       .then((res) => {
           console.log(res.data)
           setList(res.data);
       });
}, [window.location.pathname.split('/')[2]]);

useEffect(() => {
   webSocket.on('messageRecieved', (message) => {
        console.log(list);
        console.log(message);
    }); 
}, []);

Вы также можете добавить перехват ошибок, на всякий случай:

.catch((error) => {
    console.log(error.response)
})
...