[英]input onChange is wiping all elements from DOM in React. The input form works well with a button, but can't seem to work onChange on the first load
So I'm creating a grid that you can resize using two input fields on the app.所以我正在创建一个网格,您可以使用应用程序上的两个输入字段来调整它的大小。 I have the input for cells across, input for cells down and the button to set the grid which works nicely.
我有跨单元格的输入,向下的单元格输入和设置网格的按钮,效果很好。 I want to change so that the input updates the state stored on cellsAcross and cellsDown.
我想更改以便输入更新存储在 cellsAcross 和 cellsDown 上的 state。 When I remove the button and add the onChange attribute to the input elements, it works if I don't refresh the browser, but as soon as everything renders for the first time, when adding an input everything in the DOM disappears.
当我删除按钮并将 onChange 属性添加到输入元素时,如果我不刷新浏览器它会起作用,但是一旦第一次呈现所有内容,添加输入时 DOM 中的所有内容都会消失。
Here's the code with the button:这是带有按钮的代码:
function App() { const [cellsAcross, setCellsAcross] = useState(5); const [cellsDown, setCellsDown] = useState(5); const getGridSize = () => { const inputAcross = document.getElementById("cells-across").value; const cellsAcross = parseInt(inputAcross); setCellsAcross(cellsAcross); const inputDown = document.getElementById("cells-down").value; const cellsDown = parseInt(inputDown); setCellsDown(cellsDown); console.log(`Across: ${cellsAcross} | Down: ${cellsDown}`); }; return ( <div className="app"> <Header /> <CellGrid numberOfColumns={cellsAcross} numberOfRows={cellsDown} /> <label htmlFor="cells-across">Across</label> <input type="number" id="cells-across" name="cells-across" min="1" /> <br /> <label htmlFor="boxes-down">Down (1-20):</label> <input type="number" id="cells-down" name="cells-down" min="1" /> <br /> <button onClick={getGridSize}>Make Grid</button> <br /> </div> ); } export default App;
And this is what I want it to be:这就是我想要的:
import React, { useState } from "react"; import CellGrid from "./CellGrid"; import "./App.css"; import Header from "./Header"; function App() { const [cellsAcross, setCellsAcross] = useState(5); const [cellsDown, setCellsDown] = useState(5); const getGridSize = () => { const inputAcross = document.getElementById("cells-across").value; const cellsAcross = parseInt(inputAcross); setCellsAcross(cellsAcross); const inputDown = document.getElementById("cells-down").value; const cellsDown = parseInt(inputDown); setCellsDown(cellsDown); console.log(`Across: ${cellsAcross} | Down: ${cellsDown}`); }; return ( <div className="app"> <Header /> <CellGrid numberOfColumns={cellsAcross} numberOfRows={cellsDown} /> <label htmlFor="cells-across">Across</label> <input type="number" id="cells-across" name="cells-across" min="1" onChange={getGridSize} /> <br /> <label htmlFor="boxes-down">Down (1-20):</label> <input type="number" id="cells-down" name="cells-down" min="1" onChange={getGridSize} /> </div> ); } export default App;
Update onChange={()=>{setCellsAcross(e.target.valeu)}}
to just set the state value to the new value.更新
onChange={()=>{setCellsAcross(e.target.valeu)}}
以将 state 值设置为新值。 That will cause the entire component to re-render.这将导致整个组件重新渲染。
Related - it's bad practice to pull values out of the DOM directly.相关 - 直接从 DOM 中提取值是不好的做法。 If you really wanted to do get the value of that input elsewhere in code, you'd add a const myCellsAcrossRef=useRef()
and then add a ref attribute to the element:
ref={myCellsAcrossRef}`.如果您真的想在代码的其他地方获取该输入的值,您可以添加一个 const myCellsAcrossRef=useRef()
and then add a ref attribute to the element:
ref={myCellsAcrossRef}`。
Finally, you don't need your getGridSize() method if you just set the across & down values onChange, but if you did... you'd name it "setGridSize() or updateGridSize()" to indicate the method changes things.最后,如果您只是设置横向和向下值 onChange,则不需要 getGridSize() 方法,但如果您这样做了……您将其命名为“setGridSize() 或 updateGridSize()”以指示该方法改变了事物. "Get" implies the function will not have side effects/mutations.
“获取”意味着 function 不会有副作用/突变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.