在属性更改时更改状态并首先安装在 React 上 - 缺少功能?
Change state when properties change and first mount on React - Missing function?
我遇到了一个关于基于属性的状态的问题。
场景
我有一个组件 parent,它创建一个 属性 到 child 组件的传递。
Child 组件根据收到的 属性 做出反应。
在 React 中,"only" 更改组件状态的正确方法是使用函数 componentWillMount 或 componentDidMount 和 componentWillReceiveProps 就我所见(除其他外,但让我们关注这些,因为 getInitialState 只执行一次).
我的problem/Question
如果我从 parent 收到一个新的 属性 并且我想改变状态,只有函数 componentWillReceiveProps 会被执行并允许我执行 setState。渲染不允许设置状态。
如果我想在开始时设置状态和接收新的时间怎么办属性?
所以我必须在 getInitialState 或 componentWillMount/componentDidMount 上设置它。然后,您必须根据使用 componentWillReceiveProps 的属性更改状态。
当您的状态高度依赖于您的属性时,这就是一个问题,这几乎总是如此。这可能会变得愚蠢,因为您必须根据新的 属性.
重复要更新的状态
我的解决方案
我创建了一个在 componentWillMount 和 componentWillReceiveProps 上调用的新方法。我没有发现在 属性 在渲染之前更新之后以及第一次安装组件时调用了任何方法。那么就不需要做这个愚蠢的解决方法了。
无论如何,这里的问题是:当收到或更改新的 属性 时,是否有更好的选项来更新状态?
/*...*/
/**
* To be called before mounted and before updating props
* @param props
*/
prepareComponentState: function (props) {
var usedProps = props || this.props;
//set data on state/template
var currentResponses = this.state.candidatesResponses.filter(function (elem) {
return elem.questionId === usedProps.currentQuestion.id;
});
this.setState({
currentResponses: currentResponses,
activeAnswer: null
});
},
componentWillMount: function () {
this.prepareComponentState();
},
componentWillReceiveProps: function (nextProps) {
this.prepareComponentState(nextProps);
},
/*...*/
我觉得有点傻,我想我失去了一些东西......
我想还有另一种解决方案可以解决这个问题。
是的,我已经知道了:
https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html
我发现这种模式通常不是很有必要。 在一般情况下(并非总是如此),我发现根据更改的属性设置状态有点反模式;相反,只需在渲染时导出必要的 local 状态。
render: function() {
var currentResponses = this.state.candidatesResponses.filter(function (elem) {
return elem.questionId === this.props.currentQuestion.id;
});
return ...; // use currentResponses instead of this.state.currentResponses
}
然而,在某些情况下,缓存这些数据是有意义的(例如,可能计算它的成本非常高),或者出于其他原因,您只需要知道 props 何时 set/changed。在那种情况下,我基本上会使用您在问题中所写的模式。
如果你真的不喜欢输入它,你可以将这个新方法形式化为一个 mixin。例如:
var PropsSetOrChangeMixin = {
componentWillMount: function() {
this.onPropsSetOrChange(this.props);
},
componentWillReceiveProps: function(nextProps) {
this.onPropsSetOrChange(nextProps);
}
};
React.createClass({
mixins: [PropsSetOrChangeMixin],
onPropsSetOrChange: function(props) {
var currentResponses = this.state.candidatesResponses.filter(function (elem) {
return elem.questionId === props.currentQuestion.id;
});
this.setState({
currentResponses: currentResponses,
activeAnswer: null
});
},
// ...
});
当然,如果您使用基于 class
的 React 组件,您需要找到一些替代解决方案(例如继承或自定义 JS 混合),因为它们没有 React 风格立即混合。
(就其价值而言,我认为使用显式方法的代码更清晰;我可能会这样写:)
componentWillMount: function () {
this.prepareComponentState(this.props);
},
componentWillReceiveProps: function (nextProps) {
this.prepareComponentState(nextProps);
},
prepareComponentState: function (props) {
//set data on state/template
var currentResponses = this.state.candidatesResponses.filter(function (elem) {
return elem.questionId === props.currentQuestion.id;
});
this.setState({
currentResponses: currentResponses,
activeAnswer: null
});
},
我遇到了一个关于基于属性的状态的问题。
场景
我有一个组件 parent,它创建一个 属性 到 child 组件的传递。 Child 组件根据收到的 属性 做出反应。 在 React 中,"only" 更改组件状态的正确方法是使用函数 componentWillMount 或 componentDidMount 和 componentWillReceiveProps 就我所见(除其他外,但让我们关注这些,因为 getInitialState 只执行一次).
我的problem/Question
如果我从 parent 收到一个新的 属性 并且我想改变状态,只有函数 componentWillReceiveProps 会被执行并允许我执行 setState。渲染不允许设置状态。
如果我想在开始时设置状态和接收新的时间怎么办属性? 所以我必须在 getInitialState 或 componentWillMount/componentDidMount 上设置它。然后,您必须根据使用 componentWillReceiveProps 的属性更改状态。
当您的状态高度依赖于您的属性时,这就是一个问题,这几乎总是如此。这可能会变得愚蠢,因为您必须根据新的 属性.
重复要更新的状态我的解决方案
我创建了一个在 componentWillMount 和 componentWillReceiveProps 上调用的新方法。我没有发现在 属性 在渲染之前更新之后以及第一次安装组件时调用了任何方法。那么就不需要做这个愚蠢的解决方法了。
无论如何,这里的问题是:当收到或更改新的 属性 时,是否有更好的选项来更新状态?
/*...*/
/**
* To be called before mounted and before updating props
* @param props
*/
prepareComponentState: function (props) {
var usedProps = props || this.props;
//set data on state/template
var currentResponses = this.state.candidatesResponses.filter(function (elem) {
return elem.questionId === usedProps.currentQuestion.id;
});
this.setState({
currentResponses: currentResponses,
activeAnswer: null
});
},
componentWillMount: function () {
this.prepareComponentState();
},
componentWillReceiveProps: function (nextProps) {
this.prepareComponentState(nextProps);
},
/*...*/
我觉得有点傻,我想我失去了一些东西...... 我想还有另一种解决方案可以解决这个问题。
是的,我已经知道了: https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html
我发现这种模式通常不是很有必要。 在一般情况下(并非总是如此),我发现根据更改的属性设置状态有点反模式;相反,只需在渲染时导出必要的 local 状态。
render: function() {
var currentResponses = this.state.candidatesResponses.filter(function (elem) {
return elem.questionId === this.props.currentQuestion.id;
});
return ...; // use currentResponses instead of this.state.currentResponses
}
然而,在某些情况下,缓存这些数据是有意义的(例如,可能计算它的成本非常高),或者出于其他原因,您只需要知道 props 何时 set/changed。在那种情况下,我基本上会使用您在问题中所写的模式。
如果你真的不喜欢输入它,你可以将这个新方法形式化为一个 mixin。例如:
var PropsSetOrChangeMixin = {
componentWillMount: function() {
this.onPropsSetOrChange(this.props);
},
componentWillReceiveProps: function(nextProps) {
this.onPropsSetOrChange(nextProps);
}
};
React.createClass({
mixins: [PropsSetOrChangeMixin],
onPropsSetOrChange: function(props) {
var currentResponses = this.state.candidatesResponses.filter(function (elem) {
return elem.questionId === props.currentQuestion.id;
});
this.setState({
currentResponses: currentResponses,
activeAnswer: null
});
},
// ...
});
当然,如果您使用基于 class
的 React 组件,您需要找到一些替代解决方案(例如继承或自定义 JS 混合),因为它们没有 React 风格立即混合。
(就其价值而言,我认为使用显式方法的代码更清晰;我可能会这样写:)
componentWillMount: function () {
this.prepareComponentState(this.props);
},
componentWillReceiveProps: function (nextProps) {
this.prepareComponentState(nextProps);
},
prepareComponentState: function (props) {
//set data on state/template
var currentResponses = this.state.candidatesResponses.filter(function (elem) {
return elem.questionId === props.currentQuestion.id;
});
this.setState({
currentResponses: currentResponses,
activeAnswer: null
});
},