The question is, for example, there are 4 buttons, when you click on a button, the text in it should change to "Open", now the problem is that if you click on 1 button, the text will change in all buttons, is there any An elegant solution for such a problem? I can not figure it out, thanks.

import React from "react"; import ReactDOM from "react-dom"; import "./styles.css"; class App extends React.Component { state = { open: false }; handleOpen = () => { this.setState({ open: !this.state.open }); }; render() { const { open } = this.state; return ( <div> <button onClick={this.handleOpen}> {open ? "Открыто" : "Закрыто"} </button> <button onClick={this.handleOpen}> {open ? "Открыто" : "Закрыто"} </button> <button onClick={this.handleOpen}> {open ? "Открыто" : "Закрыто"} </button> <button onClick={this.handleOpen}> {open ? "Открыто" : "Закрыто"} </button> </div> ); } } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); 

    2 answers 2

    If you have a version of Reactor 16.8.0 and higher, you can get rid of the class component and use the useState hook to useState the state of the buttons:

     import React, { useState } from "react"; import ReactDOM from "react-dom"; import "./styles.css"; const App = () => { const [buttons, setButtons] = useState([ { open: false }, { open: false }, { open: false }, { open: false } ]); const handleOpen = id => { const newButtons = buttons; newButtons[id].open = !buttons[id].open; setButtons(newButtons); }; return ( <div> {buttons.map(({ open }, idx) => ( <button key={idx} onClick={() => handleOpen(idx)}> {open ? 'Открыто' : 'Закрыто'} </button> ))} </div> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); 

    If you do not want to upgrade to the latest version of the reactor, you can do the following:

     import React, { Component } from "react"; import ReactDOM from "react-dom"; import "./styles.css"; class App extends Component { state = { buttons: [ { open: false }, { open: false }, { open: false }, { open: false } ] }; handleOpen = id => { const { buttons } = this.state; buttons[id].open = !buttons[id].open; this.setState({ buttons }); }; render() { const { buttons } = this.state; return ( <div> {buttons.map(({ open }, idx) => ( <button key={idx} onClick={() => this.handleOpen(idx)}> {open ? 'Открыто' : 'Закрыто'} </button> ))} </div> ); } } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); 

    • What will you do if such buttons will be 50 pieces? For each prescribe open: false ? - meine
    • @meine, of course, you can use an array or an object. An example solves another problem 😇 - Smolin Pavel 6:26 pm
    • Nevertheless, I think that it is worth not only solving the problem, but also “making a reserve for the future.” - meine

    CodeSandbox

    index.js

     import React, { Component } from "react"; import ReactDOM from "react-dom"; import Button from "./Button"; export default class App extends Component { state = { data: [ { buttons: [ { name: "Открыто" }, { name: "Открыто" }, { name: "Открыто" }, { name: "Открыто" } ] } ] }; render() { const { data } = this.state; return ( <div> {data[0].buttons.map((button, index) => ( <Button key={index} name={button.name} /> ))} </div> ); } } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); 

    Button.js

     import React, { Component } from "react"; class Button extends Component { state = { isOpen: false }; handleOpen = () => { this.setState({ isOpen: !this.state.isOpen }); }; render() { const { isOpen } = this.state; return ( <button onClick={this.handleOpen}> {isOpen ? this.props.name : "закрыто"} </button> ); } } export default Button;