React组件存入useState变量后无法更新的原因及解决方案咨询
问题原因与解决方案
问题原因
当你把<Wait text={waitMessage}/>存入useState时,这个组件实例就被固定下来了——它携带的是当时渲染时的waitMessage值。后续waitMessage更新触发组件重渲染,但waitComp这个state变量并没有被重新赋值,所以它始终是最初创建的那个<Wait>组件,自然不会显示新的文本。
而直接渲染wait的话,每次组件重渲染(比如waitMessage变化时),wait都会重新生成一个新的<Wait>组件,自动带上最新的waitMessage,所以能正常更新。
解决方案
方案一:监听waitMessage更新waitComp
既然要把组件存在state里,就需要在waitMessage变化时,主动更新waitComp的state。可以用useEffect监听waitMessage的变化,重新生成组件并赋值:
function App() { const dependencies: string[] = []; const [waitMessage, setWaitMessage] = useState("Waiting for Server Auth..."); const [waitComp, setWaitComp] = useState(<Wait text={waitMessage}/>); const checkStatus = () => { const ajaxSet: AjaxType = { callback(request: XMLHttpRequest): void { const response = request.response; console.info(response); setWaitMessage("Response Received..."); }, params: {}, url: "http://localhost:8080/user/status" }; callAjax(ajaxSet); }; useEffect(() => { checkStatus(); }, dependencies); // 监听waitMessage变化,更新waitComp useEffect(() => { setWaitComp(<Wait text={waitMessage}/>); }, [waitMessage]); return <Router> <Switch> <Route exact path="/"> {waitComp} </Route> <Route> <PageNotFound/> </Route> </Switch> </Router>; }
方案二:存储切换状态而非组件(更推荐)
如果你的需求是根据条件切换组件,完全没必要把组件本身存在state里,只需存储一个状态标识(比如布尔值、枚举值),在渲染时动态生成组件即可。这种方式更符合React的状态管理逻辑,也避免了固定组件实例的问题:
function App() { const dependencies: string[] = []; const [waitMessage, setWaitMessage] = useState("Waiting for Server Auth..."); // 存储是否显示Wait组件的状态,可根据业务需求调整 const [showWaitComponent, setShowWaitComponent] = useState(true); const checkStatus = () => { const ajaxSet: AjaxType = { callback(request: XMLHttpRequest): void { const response = request.response; console.info(response); setWaitMessage("Response Received..."); // 示例:请求完成后切换组件 // setShowWaitComponent(false); }, params: {}, url: "http://localhost:8080/user/status" }; callAjax(ajaxSet); }; useEffect(() => { checkStatus(); }, dependencies); return <Router> <Switch> <Route exact path="/"> {/* 根据状态动态渲染,自动获取最新的waitMessage */} {showWaitComponent ? <Wait text={waitMessage}/> : <YourOtherComponent/>} </Route> <Route> <PageNotFound/> </Route> </Switch> </Router>; }
内容的提问来源于stack exchange,提问作者Himanshu Agrawal
相关产品推荐
相关产品推荐

