我有这个代码:
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>
);
}
问题在于 let chatProps = useMultiChatLogic('xxxx-xx-x-xx-xxx', username, Secret); 在 useEffect 完成之前运行。我尝试将其移至 .then 内部,但它给出了钩子错误和其他一些东西,但没有任何效果。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
我认为您缺少对 React 的基本了解。查看有关状态、
useEffect和一般控制流的教程。useEffect是异步的——首次渲染后以及每当设置依赖项数组中捕获的变量时,React 都会执行回调。您的依赖项数组为空,因此此useEffect在组件的生命周期中(在第一次渲染之后)运行一次。我不知道 Multi 是什么,但你可以尝试这样的东西:
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 (
);
};
在这里,在第一次渲染时,我们知道请求尚未完成,因为
username和secret仍然是默认的空字符串,因此我们渲染一条加载消息。渲染后,useEffect运行并启动请求。过了一会儿,响应到达,我们为
username和secret设置状态,这会触发另一个渲染。在此渲染上,响应中的username和secret值可用(我假设它们保证在响应中为非空字符串),因此不会渲染加载消息。相反,我们渲染ChatsPage组件,该组件接受带有响应数据的 props。额外的组件是必要的,因为像
useMultiChatLogic这样的钩子 必须在任何条件之上声明.如果这不是一个钩子,那么调用可以发生在if之后的组件函数体中,不需要额外的组件。React 的黄金法则是状态是不可变的,因此如果任何数据从一个渲染到下一个渲染发生更改,则必须通过
setState来完成,而不是=。