简体   繁体   中英

Change state in a dynamically created element in React

Let's say I have this component code:

import * as React from 'react'

export default function App() {
  const [value, setValue] = React.useState('default');
  const defaultPanes = new Array(1).fill(null).map((_, index) => {
    const id = String(index + 1);
    return {
      label: `Some label`,
      children: (
        <div>
          Child {id}, value: {value}
        </div>
      ),
      key: id,
    };
  });
  const [items, setItems] = React.useState(defaultPanes);
  console.log(items, value);

  return (
    <div>
      <h1>{items[0].label}</h1>
      <div>{items[0].children}</div>
      <p onClick={() => setValue('new value')}>Klick me</p>
    </div>
  );
}

How can I change the state {value} in this dynamically rendered element "defaultPanes"?

Link to this code in Stackblitz

Your items array shouldn't be a state value, and instead, you should just use defaultPanes /a regular variable. JSX shouldn't be part of state exactly for the reason you've shown. State values only update when they're explicitly told to update via the state setter function ( setItems in your case) and not when values used within the state change. If you find that you have state that relies on other state values or props, aren't using the state setter function, or are including JSX in your state, then you should think about whether your state should really be a state value. Instead, I would suggest using useMemo() to create your items array when value changes:

 function App() { const [value, setValue] = React.useState('default'); const items = React.useMemo(() => new Array(1).fill(null).map((_, index) => { const id = String(index + 1); return { label: `Some label`, children: ( <div> Child {id}, value: {value} </div> ), key: id, }; }), [value]); return ( <div> <h1>{items[0].label}</h1> <div>{items[0].children}</div> <p onClick={() => setValue('new value')}>Click me</p> </div> ); } ReactDOM.createRoot(document.body).render(<App />);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.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