所以我有这个组件:
import React from 'react';
import PropTypes from 'prop-types';
import { isEqual } from 'lodash';
class SomeComponent extends React.Component {
static propTypes = {
onChange: PropTypes.func,
};
previousItems = [];
constructor(props) {
super(props);
this.state = {
items: ['some', 'list'],
};
}
setState(stateSetter) {
super.setState(previousState => {
const newState = stateSetter(previousState);
if (!isEqual(newState.items, this.previousItems)) {
this.props.onChange && this.props.onChange(newState.items);
this.previousItems = newState.items;
}
return newState;
});
}
}
而我正在尝试做的是听取状态变化并在状态发生变化时触发onChange
。我曾经使用componentWillUpdate
做到这一点,但我听说React 17会改变。
现在正确的做法是什么?我上面所做的事情让人觉得很难过。
谢谢!
答案 0 :(得分:2)
Check the docs for componentDidUpdate()
这是副作用发生的地方,如ajax调用或在这种情况下,调用onChange,但你必须检查道具是否真的改变了(就像你在代码中所做的那样)。
请注意,此方法不会在初始渲染中调用,仅在下次更新时调用。非常适合onChange活动。
请注意,如果onChange方法设置状态,它可以启动无限循环(fire onChange - > set state - > fire onChange - > ....)。如有必要,检查状态/道具改变了什么,并仅在必要时触发onChange事件(避免无限循环)。
答案 1 :(得分:1)
要清理,这里是即将推出的React更新路径的简短描述。弃用警告将在下一个次要的React更新中推出,因此早在16.4中,弃用的方法将一直有效,直到下一个主要版本17更新。
我不建议在setState
生命周期方法中执行componentDidUpdate
,因为它会让你非常容易受到infite循环的攻击。</ p>
我不太确定您尝试通过检查state
是否已更改并且状态更改应始终由用户操作引起来实现的目标。当您调用setState tho时,您的组件将自动重新呈现。
为了清理事情,我会自己做这样的事情。您可以根据用户操作进行状态更改,并且在调用setState时,React组件将始终重新呈现。这是Reacts的本性。
如果我想传递数据,我会声明子组件并将数据作为道具传递。然后将它传递给子组件状态示例,在React 16.3 getDerivedStateFromProps
-method中新引入,它返回普通对象并自动传递给组件状态。这个方法在初始渲染时调用,并且每次组件都接收到新的道具时也是如此,所以基本上每次当你的父组件状态发生变化时,都会在这个场景中调用。
如果您不希望子组件重新呈现,您也可以return null
方法getDerivedStateFromProps
。
class MyComponent extends React.Component {
// ES7 syntax, same as doing this in constructor
// with, this.state = {}
state = {
value: false
}
handleClick = () => {
/* Might as well write some logic here
* and do setState at end
*/
const { value } = this.state
/* and at end, well I just return value negated back */
this.setState({
value: !value
})
}
render() {
const { value } = this.state
return (
<div>
{value ? 'im true' : 'im falsy'}
<button onClick={this.handleClick} >Click me!</button>
<SomeOtherComponent {...this.state} />
</div>
)
}
}
class SomeOtherComponent extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.value) {
return { text: 'it was true ' }
}
return { text: 'it was falsy' }
}
state = {
text: null,
}
render() {
return (
<div>
{ this.state.text }
</div>
)
}
}