React应用触发过多重渲染错误求助(附源码)
解决React "Too many re-renders" 错误
错误原因
你代码里的if-else判断逻辑直接写在组件函数顶层,每次组件渲染都会执行这段代码,而里面的setBtnDisabled和setMessage会触发组件重新渲染。重新渲染后又会再次执行这段逻辑、调用setState,形成无限循环,最终触发React的渲染次数限制报错。
解决方案一:用useEffect监听text变化
通过useEffect钩子,只在text状态改变时才执行状态更新逻辑,避免每次渲染都触发setState:
import { useState, useEffect } from "react"; import Card from "./shared/Card"; import Button from "./shared/Button"; const FeedbackForm = () => { const [text, setText] = useState(''); const [btnDisabled, setBtnDisabled] = useState(true); const [message, setMessage] = useState(''); // 仅当text变化时执行状态更新 useEffect(() => { if (text === '') { setBtnDisabled(true); setMessage(null); } else if (text.trim().length <= 10) { setBtnDisabled(true); setMessage('Text must be at least 10 characters!'); } else { setBtnDisabled(false); setMessage(null); } }, [text]); // 依赖项数组:只有text改变时才触发 const handleTextChange = (e) => { setText(e.target.value); }; return ( <Card> <form> <h2>How would you rate your service with us?</h2> <div className="input-group"> <input type='text' onChange={handleTextChange} placeholder='Write a review' value={text} /> <Button type='submit' isDisabled={btnDisabled}>Send</Button> </div> {message && <div>{message}</div>} </form> </Card> ); } export default FeedbackForm;
解决方案二:直接计算状态(更简洁)
btnDisabled和message不需要单独存为state,它们可以通过text直接计算得出,这样能减少不必要的state更新,更符合React最佳实践:
import { useState } from "react"; import Card from "./shared/Card"; import Button from "./shared/Button"; const FeedbackForm = () => { const [text, setText] = useState(''); // 直接根据text计算按钮状态和提示信息 const btnDisabled = text === '' || text.trim().length <= 10; const message = text !== '' && text.trim().length <= 10 ? 'Text must be at least 10 characters!' : null; const handleTextChange = (e) => { setText(e.target.value); }; return ( <Card> <form> <h2>How would you rate your service with us?</h2> <div className="input-group"> <input type='text' onChange={handleTextChange} placeholder='Write a review' value={text} /> <Button type='submit' isDisabled={btnDisabled}>Send</Button> </div> {message && <div>{message}</div>} </form> </Card> ); } export default FeedbackForm;
内容的提问来源于stack exchange,提问作者Shantanu Singh
相关产品推荐
相关产品推荐

