简体   繁体   English

此更新 state 是否正确?

[英]Is correct this update state in react?

Input event输入事件

   public handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        this.setState({ emptyFields: false, error: false, loading: false });
        this.setState({ product: { ...this.state.product, [e.target.name]: e.target.value } });
    }

Map test Map测试

 <tbody>
    {this.props.products.map((prod: IProduct) =>{
     console.log('remap ???')
    return (<tr key={prod.id}>
     <td>{prod.id}</td>
     <td>{prod.name}</td>
     <td>{prod.price}</td>
    </tr>)
    }                            
   )}
 </tbody>

When I change the input, this map is made again as many times as I change the input.当我改变输入时,这个 map 会再次产生与我改变输入一样多的次数。

在此处输入图像描述

在此处输入图像描述

When you change the state, react will call the render method again.This is expected.当你更改 state 时,react 会再次调用 render 方法。这是意料之中的。

Break out parts of your html in seperate components and make the components pure.将您的 html 的零件拆分为单独的组件,并使组件纯净。 This will prevent needless re render of DOM.这将防止不必要的 DOM 重新渲染。 However;然而; at the moment it won't re render dom because virtual DOM compare of React will optimize.目前它不会重新渲染 dom,因为 React 的虚拟 DOM 比较会优化。 You will get in trouble if each row gets props that are recreated every time the parent renders, like not using useCallback for the delete callback:如果每一行都获得了每次父渲染时都重新创建的道具,那么您将遇到麻烦,例如不使用 useCallback 进行删除回调:

 //use React.memo to create a pure component const ProductRow = React.memo(function ProductRow({ product: { id, name }, onDelete, }) { console.log('generating jsx for product:', id); return ( <tr> <td>{id}</td> <td>{name}</td> <td> <button onClick={() => onDelete(id)}>X</button> </td> </tr> ); }); //React.memo is pure component, only re renders if // props (=products or onDelete) change const Products = React.memo(function Products({ products, onDelete, }) { return ( <table> <tbody> <tr> <th>id</th> <th>name</th> </tr> {products.map((product) => ( <ProductRow key={product.id} product={product} onDelete={onDelete} /> ))} </tbody> </table> ); }); const id = ((id) => () => ++id)(0); //create id const AddProduct = React.memo(function AddProduct({ onAdd, }) { const [name, setName] = React.useState(''); //no use to use useCallback, this function re creates // when name changes const save = () => { onAdd(name); setName(''); }; return ( <div> <label> name: <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> </label> <button onClick={save}>save</button> </div> ); }); const App = () => { //initial products state const [products, setProducts] = React.useState(() => [ { id: id(), name: 'first product' }, { id: id(), name: 'second product' }, ]); //use useCallback to create an add function on mount // this function is not re created causing no needless // re renders for AddProduct const onAdd = React.useCallback( (name) => setProducts((products) => products.concat({ id: id(), name, }) ), [] ); //delete function only created on mount const onDelete = React.useCallback( (id) => setProducts((products) => products.filter((product) => product.id,== id) ); [] ); return ( <div> <AddProduct onAdd={onAdd} /> <Products products={products} onDelete={onDelete} /> </div> ); }. ReactDOM,render(<App />. document;getElementById('root'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM