为什么 useState react hook 会导致 Too many re-renders。 React 限制渲染次数以防止无限循环?

Why does useState react hook cause Too many re-renders. React limits the number of renders to prevent an infinite loop?

我有以下脚本

    const [setList, setSetList] = useState({ data: null });
    const [currentUser, setCurrentUser] = useState({ data: null });
    const [username, setUserName] = useState();
    
    const Token = localStorage.getItem('token')
    console.log(Token)
    useEffect(() => {
        const fetchData = async () => {
            const setlist = await axios.get(
                'http://127.0.0.1:8000/api/set/list/', {
                    headers: {
                        Authorization: `Token ${Token}`
                    }
            });
            const setuserdata = await axios.get(
                'http://127.0.0.1:8000/api/user/current/', {
                    headers: {
                        Authorization: `Token ${Token}`
                    }
            });
            setCurrentUser({ data: setuserdata.data });
            setSetList({ data: setlist.data });
            };
            
            fetchData();
        }, []);
        
        console.log('render');
    if (currentUser.data) {
        console.log("userdata", currentUser.data);
        console.log("userdata", currentUser.data.username);
        **setUserName(currentUser.data.username);**

    }

尝试调用 setUserName 会导致重新呈现过多。 React 限制渲染的数量以防止无限循环。我似乎找不到原因。

因为您在每次渲染时调用 setUserName 。设置状态会触发重新渲染。因此,在每次渲染时都会触发重新渲染。

如果您希望在 currentUser.data 更改时触发某些内容,那么不要在每次渲染时都检查它,而是在 useEffect 挂钩中检查它。例如:

useEffect(() => {
  // currentUser.data has changed, update something
}, [currentUser.data]);

但是在这种特殊情况下您根本不需要这些。您正在复制状态中的值:

const [currentUser, setCurrentUser] = useState({ data: null });
const [username, setUserName] = useState();

既然 usernamecurrentUser 的一部分,那么您 不需要 username,因为您有 currentUser。只需完全删除 username 状态和任何 setting/using 状态的代码,并改为引用 currentUser.data.username

如果你想为 username 使用 shorthand,这样你就不必每次都写 currentUser.data,那么不要在状态中跟踪它,只需在渲染时设置一个值:

const username = currentUser?.data?.username;