ReactJS [SOLVED]: react doesn't rerender component when props changed

ReactJS [SOLVED]: react doesn't rerender component when props changed

Home Forums Frameworks ReactJS ReactJS [SOLVED]: react doesn't rerender component when props changed

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #109595

    Cloudy Point
    Keymaster

    QuestionQuestion

    I’m changing the class attribute of my props and then i want the component to rerender with the new classes but that doesn’t work. I’ve read about the shouldComponentUpdate method but that method never gets called.

      var ReactDOM = require('react-dom');
      var React = require('react');
    
       class Button extends React.Component {
    constructor(props) {
        super(props);
        console.log("BUTTON")
        console.log(props);
        var options = props.options;
    }
    componentWillMount () {
        var defaultFeatureOptionId = this.props.feature.DefaultFeatureOptionId;
        this.props.options.forEach((option) => {
            var classes = "";
            if (option.Description.length > 10) {
                classes = "option-button big-button hidden";
            } else {
                classes = "option-button small-button hidden";
            }
            if (option.Id === defaultFeatureOptionId) {
                classes = classes.replace("hidden", " selected");
                option.selected = true;
            }
            option.class = classes;
        });
    }
    shouldComponentUpdate(props) {
        console.log("UPDATE");
    }
    toggleDropdown(option, options) {
        console.log(option);
        console.log(options)
    
        option.selected = !option.selected;
        options.forEach((opt) => {
            if (option.Id !== opt.Id) {
                opt.class = opt.class.replace("hidden", "");
            }
            else if(option.Id === opt.Id && option.selected) {
                opt.class = opt.class.replace("", "selected");
            } 
        });        
    }
    render() {
        if (this.props.options) {
            return (<div> {
                this.props.options.map((option) => {
                    return <div className={ option.class } key={option.Id}>
                        <div> {option.Description}</div>
                        <img className="option-image" src={option.ImageUrl}></img>
                        <i className="fa fa-chevron-down" aria-hidden="true" onClick={() => this.toggleDropdown(option, this.props.options) }></i>
                        </div>
                })
            }
    
            </div>
            )
        }     
        else {
            return <div>No options defined</div>
        }
    }
     }
    
     module.exports = Button;
    

    I have read a lot of different thing about shouldComponentUpdate and componentWillReceiveProps but there seems to be something else i’m missing.

    #109596

    Cloudy Point
    Keymaster

    Accepted AnswerAnswer

    You cannot change the props directly, either you call a parent function to change the props that are passed to your component or in your local copy that you createm you can change them. shouldComponentUpdate is only called when a state has changed either directly or from the props, you are not doing any of that, only modifying the local copy and hence no change is triggered

    Do something like

    var ReactDOM = require('react-dom');
    var React = require('react');
    
       class Button extends React.Component {
    constructor(props) {
        super(props);
        console.log(props);
        this.state = {options = props.options};
    }
    componentWillRecieveProps(nextProps) {
      if(nextProps.options !== this.props.options) {
        this.setState({options: nextProps.options})
      }
    }
    componentWillMount () {
        var defaultFeatureOptionId = this.props.feature.DefaultFeatureOptionId;
        var options = [...this.state.options]
        options.forEach((option) => {
            var classes = "";
            if (option.Description.length > 10) {
                classes = "option-button big-button hidden";
            } else {
                classes = "option-button small-button hidden";
            }
            if (option.Id === defaultFeatureOptionId) {
                classes = classes.replace("hidden", " selected");
                option.selected = true;
            }
            option.class = classes;
        });
        this.setState({options})
    }
    shouldComponentUpdate(props) {
        console.log("UPDATE");
    }
    toggleDropdown(index) {
    
        var options = [...this.state.options];
        var options = options[index];
        option.selected = !option.selected;
        options.forEach((opt) => {
            if (option.Id !== opt.Id) {
                opt.class = opt.class.replace("hidden", "");
            }
            else if(option.Id === opt.Id && option.selected) {
                opt.class = opt.class.replace("", "selected");
            } 
        });   
        this.setState({options})
    }
    render() {
        if (this.state.options) {
            return (<div> {
                this.state.options.map((option, index) => {
                    return <div className={ option.class } key={option.Id}>
                        <div> {option.Description}</div>
                        <img className="option-image" src={option.ImageUrl}></img>
                        <i className="fa fa-chevron-down" aria-hidden="true" onClick={() => this.toggleDropdown(index) }></i>
                        </div>
                })
            }
    
            </div>
            )
        }     
        else {
            return <div>No options defined</div>
        }
    }
     }
    
     module.exports = Button;
    

    Source: http://stackoverflow.com/questions/43862522/react-doesnt-rerender-component-when-props-changed
    Author: Shubham Khatri
    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.