最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to change style property on button onClick in React? - Stack Overflow

programmeradmin1浏览0评论

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"

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"

Share asked May 2, 2019 at 15:16 Oscar ArranzOscar Arranz 7142 gold badges10 silver badges27 bronze badges 4
  • In my current project, I utilized jquery in the ponentDidMount() method to acplish this. I've seen remendation against this, however, so I too would like to see thoughts on this. – silencedogood Commented May 2, 2019 at 15:20
  • If you use jquery in react (if you are not wrapping a non-react library) may be you are using it in the wrong way. There are multiple approach to this task, and the simpliest is to define two classes in you CSS and switch className (without relying on jQuery) – Mosè Raguzzini Commented May 2, 2019 at 15:24
  • @MosèRaguzzini well I didn't import jquery simply for the toggle method that's for sure. But I get what you're saying, I've utilized vanilla js and css for this task as well. My point really is just that including all these different things in the ponent state gets tedious. My perception of state was that it is meant to keep track of user input data. When you start getting into storing basic UI functionality in state, just seems overkill I guess. I'll have to get used to this notion as it's apparently the 'correct' way. – silencedogood Commented May 2, 2019 at 15:46
  • It dependes, I usually store the UI state in Redux along with datas as when a bug is detected BugSnag send the plete history of states to my debugger and I can reproduce both data and UI state when error occurred. It is sure that is better to manage the single css in CSS/Styled-ponents/SASS/LESS or similar and take in consideration to work simply with classes – Mosè Raguzzini Commented May 2, 2019 at 16:01
Add a ment  | 

5 Answers 5

Reset to default 4

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>
}

What I would do is style your ponent 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 ponent 
// 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.

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.

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;
}
发布评论

评论列表(0)

  1. 暂无评论