【问题标题】:ReactJS: useEffect not updating state value on API callReactJS:useEffect 不更新 API 调用的状态值
【发布时间】:2021-06-25 08:26:33
【问题描述】:

我想在 API 成功响应时更新状态值。并根据更新后的状态值想执行下一个流程。

const App = () => {

    const [chatClient, setChatClient] = useState(null);
    const [channel, setChannel] = useState(null);
    const [chatToken, setChatToken] = useState(null);

    useEffect(() => {
        const initChat = async () => {
            const client = StreamChat.getInstance(process.env.API_KEY);
            await axios.get(`${process.env.API_URL}/generate_token?username=johndoe`, {
            })
                .then((response) => {
                    if (response && response.status === 200) {
                        const _token = response.data.token
                        setChatToken(_token)
                        console.log(chatToken); // returns null value
                    }
                })
            await client.disconnectUser()
            await client.connectUser({ id: userName }, chatToken); // Getting the chatToken value as null
            const _channel = await client.channel(process.env.TYPE, process.env.ROOM);
            setChatClient(client);
            setChannel(_channel)
        };

        initChat();
    }, []);

    return (
        <Chat client={chatClient} theme='livestream dark'>
            <Channel channel={channel}>
                ...
            </Channel>
        </Chat>
    );
};

export default App;

我正在关注这个answer,但仍然缺少一些我无法弄清楚的东西。

【问题讨论】:

  • 状态更新是异步的。当前状态值始终是渲染组件的值。在下一次渲染之前,它不会立即反映更新。因此,您的 console.log(chatToken) 将始终只记录当前值,而不是更新值。
  • 所以我需要将该值用于另一个钩子或其他东西?
  • 不,您只是没有记录新值,而是记录了旧值。更新应该可以工作。
  • 你能不能在你的 useEffect 钩子中做 console.log(response),看看你是否得到了响应
  • 然后要么使用response.data.token,要么将其包装在另一个具有chatToken作为依赖项的效果中。

标签: reactjs react-hooks use-effect


【解决方案1】:

由于您的 useEffect 仅在初始渲染时运行,因此 useEffect 中的 chatToken 仍然引用闭包中的旧值。这里的解决方案是直接使用api中的chatToken。

useEffect(() => {
    const initChat = async () => {
        const client = StreamChat.getInstance(process.env.API_KEY);
        const token = await axios.get(`${process.env.API_URL}/generate_token?username=johndoe`, {
        })
            .then((response) => {
                if (response && response.status === 200) {
                    const _token = response.data.token
                    setChatToken(_token)
                    return  _token;
                }
            })
        await client.disconnectUser()
        await client.connectUser({ id: userName }, token);
        const _channel = await client.channel(process.env.TYPE, process.env.ROOM);
        setChatClient(client);
        setChannel(_channel)
    };

    initChat();
}, []);

查看这篇文章,了解为什么在调用 setState 后状态更新没有反映以了解更多详细信息:

useState set method not reflecting change immediately

【讨论】:

    猜你喜欢
    • 2021-08-17
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多