React/Next.js API调用后更新状态仍无法渲染组件数组问题求助
你遇到的问题本质是函数组件的普通局部变量不会在重渲染之间保留状态。当你调用setShowMatch(true)触发组件重渲染时,组件函数会重新执行,代码里的let matches = []会被重新初始化,你之前在接口请求回调中填充的组件内容全部被清空,所以渲染出来的永远是空数组。
你在控制台看到数组有值,是因为打印行为发生在重渲染之前,当时的局部变量还没被重置,重渲染之后的渲染上下文用的是新初始化的空数组,所以才会出现日志有值但渲染为空的情况。
解决方案
把存储组件数组的matches改为React状态即可,不需要额外维护showMatch布尔状态,直接通过数组长度判断是否要渲染内容即可,同时要给循环渲染的组件添加唯一key属性避免React告警。
修改后的代码如下:
function Form() { // 控制HeadingText组件显隐的状态 const [showResults, setShowResults] = React.useState(true) // 存储要渲染的Match组件数组的状态 const [matches, setMatches] = React.useState([]) const registerUser = async event => { event.preventDefault() // 阻止页面默认跳转行为 // 隐藏HeadingText组件,仅展示赛事数据 setShowResults(false) // 调用接口传递用户输入的赛事链接 const res = await fetch('/api/register', { body: JSON.stringify({ matchLink: event.target.matchLink.value }), headers: { 'Content-Type': 'application/json' }, method: 'POST' }) const result = await res.json() console.log(result) // 生成Match组件数组并更新状态 const tempMatches = [] for (let i = 0; i < 3; i++) { tempMatches.push(<Match key={i} // 循环渲染必须加唯一key title={`game ${i} `} nOfGame={i} game={result.rounds[i]} />); } setMatches(tempMatches) } return ( <> {/* 控制HeadingText显隐 */} { showResults ? <HeadingText /> : null } <div className="form-container"> <form onSubmit={registerUser}> <input type="text" name="matchLink" id="textFiledId" placeholder="插入演示链接" /> <input type="submit" value="搜索" name="subDemo" /> </form> </div> {/* matches数组非空时渲染内容 */} <div className="match-holder"> { matches.length > 0 ? matches : null } </div> <p>{matches.length}</p> </> ) } export default Form
如果业务逻辑确实需要单独的布尔状态控制显隐,也可以保留showMatch变量,核心修改点还是要把matches改为state存储,否则重渲染后内容还是会丢失。
内容的提问来源于stack exchange,提问作者noxter
相关产品推荐
相关产品推荐

