TMA
TMA

Reputation: 1489

ReactJS: useEffect not updating state value on API call

I would like to update the state value when on API success response. And based on the updated state value would like to perform the next process.

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;

I am following this answer but still there is something missing that I can not figure out.

Upvotes: 0

Views: 1384

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281626

Since your useEffect is run only on the initial render, the chatToken inside the useEffect is still referencing the old value from the closure. The solution here would be to use the chatToken from api directly.

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();
}, []);

Check this post on why state updates don't reflect after calling setState for more details:

useState set method not reflecting change immediately

Upvotes: 1

Related Questions