I am rendering some data from array of object which contains button. I am appending button text from state which is set initially as "Select". What I want is when I click on any button then its value should get update as "Selected". Currently all button values are getting update when I click on any button.
const TestPage = () =>{
let buttons = [
{name:'Select1', id:1},
{name:'Select2', id:2},
{name:'Select3', id:3}
]
const [btnText, setbtnText] = useState('Select')
const handleClick = () =>{
setbtnText('Selected')
}
return(
<div>
{!!buttons && buttons.map(item =>{
return(
<p key={item.id}>
<Button btnType='button' btnText={btnText} clickHandler={handleClick} />
</p>
)
})}
</div>
)
}
export default TestPage;
CodePudding user response:
Each button needs to have its own state. When you share one variable between multiple buttons, all will change if any handler changes the single variable.
const Example = () => {
const [buttons, setButtons] = React.useState([
{name: "Select1", id: 1},
{name: "Select2", id: 2},
{name: "Select3", id: 3},
]);
const handleButtonClick = i => {
setButtons(prevState => [
...prevState.slice(0, i),
{...prevState[i], name: "Selected"},
...prevState.slice(i 1),
]);
};
return (
<div>
{buttons.map(({name, id}, i) =>
<button
key={id}
onClick={() => handleButtonClick(i)}
>
{name}
</button>
)}
</div>
);
};
ReactDOM.render(<Example />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Another approach is to pass the id
to the click handler and use const i = buttons.findIndex(btn => btn.id === id)
to determine which button's name should be changed.