gpt4 book ai didi

reactjs - 在 useEffect 中使用 useState 值而不使状态更新 useEffect

转载 作者:行者123 更新时间:2023-12-03 16:59:43 27 4
gpt4 key购买 nike

我正在开发一个基于对象键管理字符串数组的函数。假设它看起来像这样:

import React, { useState, useEffect } from "react";
import FieldContext from "../contexts/FieldContext";
import io from "socket.io-client";

const [socket, setSocket] = useState(null);
// the `data` array gets changed every second due to a WebSocket, in case that's important
const [data, setData] = useState({ foo: [], bar: [] });
const [connections, setConnections] = useState(["conn1", "conn2"]);

const { checkedFields } = useContext(FieldContext); // ["foo", "moo"];

useEffect(() => {
setConnections(prevConnections => {
// The code below does the following:
// Loop through the temporary connections (which is a copy of checkedFields)
// A. if `tempConn` is a key in the `data` object, push the name with `update_` prefix to the `_conns` array
// B. If not, just push it without a prefix to the `_conns` array
// Since the `checkedFields` array is ["foo", "moo"], the first element will get the prefix,
// the other won't and will just get pushed.
let _tempConns = [...checkedFields];
let _conns = [];
_tempConns.forEach(tempConn => {
if (data[tempConn] !== undefined) _conns.push(`update_${tempConn}`);
else _conns.push(tempConn);
});
return _conns;
});
}, [checkedFields]);

// the websocket hook
useEffect(() => {
const _socket = io(WS_URI);
_socket.on("info", data => {
// some magic happens here to add to the `data` object which is not important for this question
});
setSocket(_socket);
}, [])
使用此 Hook 时收到以下警告: React Hook useEffect has a missing dependency: 'data'. Either include it or remove the dependency array .我明白,但如果我包括 data在依赖数组中,我得到了大量不必要的更新。我该如何防止这种情况发生? (请不要使用 // eslint-disable-next-line)

最佳答案

您不仅缺少data来自 useEffect 的依赖数组钩,但你也错过了setConnections()依赖数组中的函数。
您可以使用 useReducer将状态更新逻辑移出 useEffect 的钩子(Hook)钩。

const initialState = {
data: { foo: [], bar: [] },
connections: ["conn1", "conn2"]
}

const reducerFunc = (state, action) => {
switch(action.type) {
case 'UPDATE_CONNECTIONS':
let _tempConns = [...action.checkedFields];
let _conns = [];
_tempConns.forEach(tempConn => {
if (state.data[tempConn] !== undefined) _conns.push(`update_${tempConn}`);
else _conns.push(tempConn);
});
return { ...state, connections: _conns };
default:
return state;
}
};

const [myState, dispatch] = useReducer(reducerFunc, initialState);

const { checkedFields } = useContext(FieldContext); // ["foo", "moo"];

useEffect(() => {
dispatch({ type: 'UPDATE_CONNECTIONS', payload: checkedFields });
}, [checkedFields]);
由于 React 确保 dispatch函数不会改变,你可以从 useEffect 中省略它hook 的依赖数组。
详细使用方法 useReducer Hook ,请参阅以下链接:
  • useReducer Hook - React Hooks Cheatsheet
  • useReducer Hook - React docs
  • 关于reactjs - 在 useEffect 中使用 useState 值而不使状态更新 useEffect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62658931/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com