React二次点击搜索报result.push is not a function错误如何解决
错误原因
Array.push()方法返回值是数组修改后的新长度,不是修改后的数组本身,执行setResult(result.push(data[element].studentName))后,result会直接从数组变为数字类型,后续调用push方法自然会报错。- 代码最后执行了
setResult(result.join("<br/>")),直接把result从数组改成了字符串类型,第二次点击搜索时,字符串类型的result本身就没有push方法,直接触发类型错误。 - 在循环里反复调用
setResult没有意义,React状态更新是批量异步的,同个同步流程里多次调用只会生效最后一次,前面的更新都会被覆盖。 - 直接把
<br/>作为字符串存入状态渲染时,React会转义特殊字符,不会解析成换行标签,只会显示成纯文本。
修正方案
先过滤出符合条件的学生姓名数组存入状态,渲染的时候再插入换行即可,不需要提前把换行拼进状态里。修正后的完整代码如下:
const mockFetch = () => Promise.resolve({ json: () => new Promise((resolve) => setTimeout(() => resolve({ student1: { studentName: 'student1' }, student2: { studentName: 'student2' }, student3: { studentName: 'student3' } }), 250)) }) function MyApp() { const [result, setResult] = React.useState([]); const [queryString, setQueryString] = React.useState(""); function searchHandler() { mockFetch( "{url that i defined in real code}" ) .then(response => response.json()) .then(data => { // 先过滤出符合条件的姓名数组 const matchedNames = Object.keys(data) .map(key => data[key].studentName) .filter(name => { if (queryString.trim() === "") return true return name.toLowerCase().includes(queryString.toLowerCase()) }) // 直接把数组存入状态 setResult(matchedNames) }); } return ( <div> <div> <input type = "text" placeholder = "Search..." onChange={event => setQueryString(event.target.value)} /> <button onClick={searchHandler}>Search</button> </div> <output> Result: <br /><br /> {/* 渲染时插入换行 */} {result.map((name, index) => ( <React.Fragment key={index}> {name} <br/> </React.Fragment> ))} <br /><br /><br /> <br /> Query String: <br /><br />{queryString}<br /><br /> </output> </div> ); } ReactDOM.render(<MyApp />, document.querySelector('#root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script> <div id="root"></div>
内容的提问来源于stack exchange,提问作者Airlo
相关产品推荐
相关产品推荐

