【问题标题】:react doesn't rerender component when props changed当 props 改变时,react 不会重新渲染组件
【发布时间】:2017-05-09 06:23:45
【问题描述】:

我正在更改我的道具的类属性,然后我希望组件使用新类重新呈现,但这不起作用。我已经阅读了有关 shouldComponentUpdate 方法的信息,但该方法永远不会被调用。

  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;

我已经阅读了很多关于 shouldComponentUpdate 和 componentWillReceiveProps 的不同内容,但我似乎还缺少其他内容。

【问题讨论】:

  • 根据博客我读到“只有在组件的状态发生变化时才能触发重新渲染。状态可以通过道具更改或直接 setState 更改来更改。组件获取更新状态,React 决定它是否应该重新渲染组件。“props 和 state 都会触发状态变化

标签: reactjs components


【解决方案1】:

您不能直接更改道具,您可以调用父函数来更改传递给组件的道具,或者在您创建的本地副本中更改它们。 shouldComponentUpdate 仅在状态直接更改或从道具更改时调用,您无需执行任何操作,仅修改本地副本,因此不会触发更改

做一些类似的事情

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;

【讨论】:

  • 你写这个是什么意思:[...this.state.options]?
  • 如果我使用 this.state.options 那么状态将为空。我可以使用 this.setState.options 但我认为这是错误的,因为这是用于实际设置状态的方法?
  • 查看此答案stackoverflow.com/questions/42811882/… 以了解[...this.state.options] 的含义,它创建一个重复的对象并简而言之包含在一个数组中,称为扩展运算符语法
  • 即使首先调用构造函数并设置状态。 var 选项 = [...this.state.options];在 componentWillMount 中,状态仍然为空。然而 this.setState 不是。为什么构造函数中的状态设置不正确?
  • 没关系。我在构造函数中输入了 this.setState 而不是 this.state。
猜你喜欢
  • 1970-01-01
  • 2016-08-28
  • 1970-01-01
  • 2020-04-22
  • 2019-07-12
  • 1970-01-01
  • 2020-01-20
  • 1970-01-01
  • 2021-01-14
相关资源
最近更新 更多