I have this code:
const ChatsPage = () => { let username = "" let secret = "" useEffect(() => { axios .post('http://localhost:3001/authenticate') .then((response) => { username = response.data.username secret = response.data.secret }) .catch((error) => { console.log(error); }); }, []); let chatProps = useMultiChatLogic('xxxxx-xxx-xxx-xxx-xxx', username, secret); return ( <div style={{ height: '100vh' }}> <MultiChatSocket {...chatProps} /> <MultiChatWindow {...chatProps} style={{ height: '100vh' }} /> </div> ); }
The problem is that let chatProps = useMultiChatLogic('xxxx-xx-x-xx-xxx', username, Secret);
runs before useEffect
completes. I tried moving it inside a .then but it gave hook errors and some other stuff but nothing worked.
P粉9830211772024-04-02 00:44:59
I think you are missing a basic understanding of React. Check out the tutorials on states, useEffect
, and general control flow.
useEffect
is asynchronous - React executes the callback after the first render and whenever a variable captured in the dependencies array is set. Your dependencies array is empty, so this useEffect
runs once during the component's lifecycle (after the first render).
I don't know what Multi is, but you could try something like this:
const ChatsPageLoader = () => { const [username, setUsername] = useState(''); const [secret, setSecret] = useState(''); useEffect(() => { axios .post('http://localhost:3001/authenticate') .then((response) => { setUsername(response.data.username); setSecret(response.data.secret); }) .catch((error) => { console.log(error); }); }, []); if (!username || !secret) { returnLoading...; } return; }; const ChatsPage = ({username, secret}) => { const chatProps = useMultiChatLogic('xxxxx-xxx-xxx-xxx-xxx', username, secret); return ( ); };
Here, on the first render, we know that the request has not completed yet because username
and secret
are still the default empty strings, so we render a loading message. After rendering, useEffect
runs and initiates the request.
After a while, the response arrives and we set state for username
and secret
, which triggers another render. On this render, the username
and secret
values are available in the response (I assume they are guaranteed to be non-empty strings in the response), so the loading message is not rendered. Instead, we render the ChatsPage
component, which accepts props with response data.
The extra component is necessary because hooks like useMultiChatLogic
must be declared above any conditions < /a>. If this is not a hook, then the call can occur There is no need for additional components in the component function body after if
.
The golden rule of React is that state is immutable, so if any data changes from one render to the next, it must be done via setState
, not =
.