简体   繁体   中英

how to render the state in React properly?

I have a react component and I use useState to create values like this

const [value, setValue] = useState([
    { id: 0, name: "rafi" },
    { id: 1, name: "fii" },
  ]);

and I created a function inside the react component to rename array and delete array

 function arrayObjectIndexOf(myArray, searchTerm, property) {
    for (var i = 0, len = myArray.length; i < len; i++) {
      if (myArray[i][property] === searchTerm) return i;
    }
    return -1;
  }


const renameValue = (id, name) => {
    let index = arrayObjectIndexOf(value, id, "id");
    let newValue= value;
    neValue[index]["name"] = name;
    setValue(newValue);
  };

const deleteValue= (id) => {
    let newValue= value.filter((list) => list.id !== id);
    setValue(newValue);
  };

and I render the component like this

<>
        <h1>LIST</h1>
        {value.map((list) => {
          return (
            <div key={list.id}>
              <h1>{list.name}</h1>
              <button type="button" onClick={() => deleteValue(list.id)}>
                Remove
              </button>
              <button
                type="button"
                onClick={() => renameValue(list.id, "raa")}
              >
                Rename
              </button>
            </div>
          );
        })}
    </>

In the React component, the rename button does not work (the name in the list has not changed), but when I press the rename button of the two buttons, and continue by pressing the delete button, the name in the list changes.

Is there someone who can help me on this problem. To make the rename button work properly. ask for suggestions on how to properly render components in React.

in peace. thx.

You're mutating your original state. As a result, when you return the same value for your state, react won't re-render your component. Updating the DOM can be an expensive operation, so React tries to minimize the amount of times it is updated. If your old state is equal ( === ) to your new state, then react will skip the rendering.

 const currState = [{}, {}, {}]; const newState = currState; // this does NOT create a copy, it just points newState to the same array in memory as currState currState[0] = 0; // change value (mutate original `myState`) console.log(currState === newState); // true (as exactly the same array in memory)

Instead, keep your changes immutable (ie: don't mutate your value state directly). You can do this by creating a new array with modified object values. The below code will map through your value array, which will create a new array of values, if the current object's id matches the provided id passed into your function call, then you can return a modified object with the name overwritten to be the name passed through into your function:

const renameValue = (id, name) => {
  setValue(oldValue => oldValue.map(
    obj => obj.id === id ? {...obj, name} : obj
  ));
};

See working example:

 const {useState} = React; const App = () => { const [value, setValue] = useState([ { id: 0, name: "rafi" }, { id: 1, name: "fii" }, ]); const renameValue = (id, name) => { setValue(oldValue => oldValue.map( obj => obj.id === id? {...obj, name}: obj )); }; const deleteValue= (id) => { let newValue= value.filter((list) => list.id;== id); setValue(newValue); }. return <React.Fragment> <h1>LIST</h1> {value.map((list) => { return ( <div key={list.id}> <h1>{list.name}</h1> <button type="button" onClick={() => deleteValue(list.id)}> Remove </button> <button type="button" onClick={() => renameValue(list,id; "raa")} > Rename </button> </div> ). })} </React.Fragment> } ReactDOM,render(<App />. document;body);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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