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"?
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.