简体   繁体   中英

How do I use toggle in react with states?

Having problem to find the solution of using state in React.

I've not done it with bind-method because I'd rather to make it work this way with arrow-functions.

constructor(props) {
    super(props);

    this.state = {
        isOpen: false
    };
}

toggleNavbar = () => {
    this.setState(prevState => ({
        isOpen: !prevState.isOpen;
    });
}

render() {
    const { isOpen } = this.state;

return (
  <nav className="navbar navbar-expand-lg navbar-light bg-light">
    <a className="navbar-brand mr-4" href="">Do you want to build sowman?</a>
    <button
      className="navbar-toggler"
      type="button"
      data-toggle="collapse"
      data-target="#navbarSupportedContent"
      aria-controls="navbarSupportedContent"
      aria-expanded="false"
      aria-label="Toggle navigation"
      onclick={() => this.toggleNavbar()}>
      <span className="navbar-toggler-icon" />
    </button>
    <div
      className="collapse navbar-collapse"
      id="navbarSupportedContent"
      isOpen={isOpen}>

I want the toggle-button to show/hide the div that's comming ahead.(This is just a sample of the text and won't work on its own)

In order to toggle your div based on state, you can either:

  1. Remove the semicolon ; from your setState property inside toggleNavbar .

  2. React does not allow camelcase writing for attribute names. Change isOpen to isopen in your #navbarSupportedContent div.

  3. Specify a string instead of a boolean as your isopen attribute value and based on that, change the css of the div accordingly.

You can check out a practical example with css and html of the above in this CodePen or you can check the React class component code in the Code Snippet below:

 class App extends React.Component { constructor(props) { super(props); this.state = { isOpen: false }; } toggleNavbar = () => { this.setState(prevState => ({ isOpen: !prevState.isOpen })); } render() { const { isOpen } = this.state; return ( <div> <button onClick={this.toggleNavbar}>Click Me</button> <div id="navbarSupportedContent" isopen={isOpen ? "open" : "close"}> <p>Hello World</p> </div> </div> ) } } ReactDOM.render(<App />, document.getElementById('main')); 


Or you can use the && operator as @ŁukaszBlaszyński showed above by:

  1. Removing the semicolon ; from your setState property inside toggleNavbar .

  2. Use the && operator to toggle the div depending on the isOpen state property.

You can check out a practical example of the above in this CodePen or you can check the React class component code in the Code Snippet below:

 class App extends React.Component { constructor(props) { super(props); this.state = { isOpen: false }; } toggleNavbar = () => { this.setState(prevState => ({ isOpen: !prevState.isOpen })); } render() { const { isOpen } = this.state; return ( <div> <button onClick={this.toggleNavbar}>Click Me</button> {isOpen && <div id="navbarSupportedContent" > <p>Hello World</p> </div>} </div> ) } } ReactDOM.render(<App />, document.getElementById('main')); 

Since you are using arrow functions, you just can define your property like :

onclick={this.toggleNavbar}>

and not making another arrow function inside propery

See this fiddle it works fine: https://jsfiddle.net/y5gqrf02/1/

Example code which simple toggle state and display message or not based on state. It use arrow function and simply take state isOpen negation to be updated.

class Hello extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
        isOpen: false
    };
  }

  toggleNavbar() {
      this.setState({
          isOpen: !this.state.isOpen
      });
  }

  render() {
      const { isOpen } = this.state;

      return (
         <div onClick={() => this.toggleNavbar()}>Click Me 
           {isOpen && <div>IS OPEN</div>}
         </div>
      );

  }
};

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

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