React创建二维数组及Wordle克隆参数修改后渲染异常排查
问题原因与修复方案
核心问题
你遇到的修改参数后网格变成11的问题,根源在于input输入框的value是字符串类型,而你直接把这个字符串传给了Array()构造函数。当Array()接收字符串参数时,会创建一个只包含该字符串的单元素数组(比如Array("5")得到["5"],长度为1),而非你期望的指定长度的空数组。所以修改参数后,无论是尝试次数还是单词长度,都会被当成单元素数组处理,最终渲染出11的网格。
具体修复步骤
将输入值转为数字类型
在更新state时,用Number()把input的value转成数字:let renderBox = ()=>{ setBoxParam({ nbrAttempts: Number(document.getElementById('nbAttempts').value), wordLenght : Number(document.getElementById('wordLength').value), }) }修复label的关联错误
第二个label的htmlFor属性写错了,应该对应wordLength而非nbAttempts,否则点击"Word length"标签时会聚焦到第一个输入框:<label htmlFor="wordLength">Word length</label> <input type="number" id="wordLength"/>推荐改用受控组件(更符合React规范)
直接操作DOM取元素不是React的最佳实践,建议把input的值和state绑定,变成受控组件,这样数据流更清晰,也能避免潜在的DOM操作问题:function App() { const [boxParam, setBoxParam] = useState({nbrAttempts: 4, wordLenght : 4,}); // 处理尝试次数输入变化 const handleAttemptsChange = (e) => { setBoxParam(prev => ({...prev, nbrAttempts: Number(e.target.value)})); } // 处理单词长度输入变化 const handleLengthChange = (e) => { setBoxParam(prev => ({...prev, wordLenght: Number(e.target.value)})); } // 点击OK按钮可添加数值校验 const renderBox = ()=>{ if(boxParam.nbrAttempts <1 || boxParam.wordLenght <1){ alert("请输入大于0的数值"); return; } } return ( <div className="App"> <label htmlFor="nbAttempts">Attempts</label> <input type="number" id="nbAttempts" value={boxParam.nbrAttempts} onChange={handleAttemptsChange} min="1" /> <label htmlFor="wordLength">Word length</label> <input type="number" id="wordLength" value={boxParam.wordLenght} onChange={handleLengthChange} min="1" /> <button onClick={renderBox}>OK</button> <Box nbrAttempts={boxParam.nbrAttempts} wordLenght={boxParam.wordLenght} /> </div> ); }
Box组件的补充说明
确保你的Box组件中,创建网格时使用的是数字类型的props:
class Box extends React.Component { render() { const nbrAttempts = Number(this.props.nbrAttempts); const wordLength = Number(this.props.wordLenght); const grid = Array(nbrAttempts).fill(0).map(row => new Array(wordLength).fill(' ')); return ( <div className="grid-container"> {grid.map((row, rowIdx) => ( <div key={rowIdx} className="grid-row"> {row.map((cell, colIdx) => ( <input key={colIdx} type="text" className="grid-cell" defaultValue={cell} /> ))} </div> ))} </div> ); } }
内容的提问来源于stack exchange,提问作者yahyaBdd
相关产品推荐
相关产品推荐

