简体   繁体   中英

How to change style property on button onClick in React?

I have an element in react that I want to hide when I click a button.

The element styles are loaded at the constructor like this:

 constructor(props) {
super(props);
this.state = {
  display: 'block'
};
this.ElementStyle= {
  width: '100%',
  backgroundColor: '#F6F6F6',
  color: '#404040',
  padding: '8px 15px',
  boxSizing: 'content-box',
  position: 'fixed',
  bottom: '0',
  display: this.state.display
    }
  }

And the element has got a button inside it's render() calling a function that changes state like so:

render()  {
  <button onClick={this.Method.bind(this)}>Click me </button>
}

And the Method():

  Method() {
    this.setState({
      display: 'none'
    });
  }

And then I have this:

  shouldComponentUpdate() {
    this.ElementStyle.display = this.state.display;
  }

This however is saying: "TypeError: "display" is read-only"

Simply Place your styles in state:

State

this.state = {
  ElementStyle: {
  width: '100%',
  backgroundColor: '#F6F6F6',
  color: '#404040',
  padding: '8px 15px',
  boxSizing: 'content-box',
  position: 'fixed',
  bottom: '0',
  display: 'block
};

Method

 Method() {
    this.setState({
      ElementStyle: {
      ...this.state.ElementStyle,
      display: 'none'
      }
    });
  }

Render

render()  {
  <button style={this.state.ElementStyle} onClick={this.Method.bind(this)}>Click me </button>
}

no did wrong react has a virtual dom, and it's managed automatically, but you are trying to change its behavior, I think you can do it like this:

constructor(props) {
    super(props);
    this.state = {
       display: 'block'
    };
}


Method() {
   this.setState({
       display: 'none'
   });
}


render()  {
  <div>
     <div style={{display: this.state.display}} ></div>
     <button onClick={this.Method.bind(this)}>Click me </button>
  </div>
}

you also have several options too, but it is simplest way.

What I would do is style your component and set the display initialy to none, like:

// css
.yoourclass {
 width: '100%',
  backgroundColor: '#F6F6F6',
  color: '#404040',
  padding: '8px 15px',
  boxSizing: 'content-box',
  position: 'fixed',
  bottom: '0',
  display: none
    }

}

//have a class that show display to block
.show {
  display: block;
}

Then in your javascript

// set your state to some display property 
this.state = {
   showHiddenElement: false
}

//then you can set state to display css like
const {showHiddenElement} = this.state;
this.setState({
  showHiddenElement: !showHiddenElement
})
// and in your component 
// apply the class bases on the state like
const toggle = this.state.showHiddenElement;
<yourelement className={`yoourclass ${toggle? 'show' : ''}`}

Something like that, I hope this makes sense, let me know. It is a different approach.

I am not sure why you're trying to set style using style property, but how we usually do this is using css classes and css stylesheets. And in runtime we modify classes instead of element styles.

So, for your case, we would have that style as some class like in, let's say App.scss

.class-to-be-applied {
    width: 100%;
    background-color: #F6F6F6;
    color: #404040;
    padding: 8px 15px;
    box-sizing: content-box;
    position: fixed;
    bottom: 0;

    .no-display {
        display: none;
    }
}

and in App.js ,

import React, { Component }  from 'react';
import classnames from 'classnames';
import './App.scss';

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            display: true
        };
    }
    handleButtonClick = () => {
        this.setState(({ display }) => ({display: !display}));
    }
    render()  {
        return (
            <div>
                <button onClick={this.handleButtonClick}>Click me </button>
                <SomeComponent className={classnames('class-to-be-applied', {'no-display': !this.state.display})} />
            </div>
        );
    }
}

Other way to do the same thing and more preferred way is to just not render it at all to avoid inserted into the tree itself, like below for App.js ,

import React, { Component }  from 'react';
import classnames from 'classnames';
import './App.scss';

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            display: true
        };
    }
    handleButtonClick = () => {
        this.setState(({ display }) => ({display: !display}));
    }

    render()  {
        return (
            <div>
                <button onClick={this.handleButtonClick}>Click me </button>
                { this.state.display && <SomeComponent className=class-to-be-applied' /> }
            </div>
        );
    }
}

1) Put your object inside inline CSS :-

render() {
    return (
        <div>
            <button onClick={ this.Method.bind(this) }>Click me </button>
            <h1 style={{
                 width: '100%',
                 backgroundColor: '#F6F6F6',
                 color: '#404040',
                 padding: '8px 15px',
                 boxSizing: 'content-box',
                 position: 'fixed',
                 bottom: '0',
                 display:this.state.display
            }}>About</h1>
        </div>
    )
}

2) And remove this shouldComponentUpdate() function

 shouldComponentUpdate() {
this.ElementStyle.display = this.state.display;
}

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