通过 componentDidMount 中的道具设置状态时出现问题
Problem setting state via props in componentDidMount
我有一个问题,但我找不到原因,我相信这与我缺乏反应经验有关,那我们走吧。当组件被安装时,componentDIdMount 被调用并插入道具的状态,但是当我刷新页面(f5)时,单位和时区状态没有收到 didMount 的值,但是状态测试收到它的值,它是好像 this.pros 在 componentDidMount 中不存在但它在组件上。
When the component is rendered.
When refresh to page (f5).
我看到刷新时调用了componentDidMount,因为测试插入状态,但是this.props不是。有人把灯指向隧道尽头吗?
My component.
import React, {Component} from 'react'
import { connect } from 'react-redux';
import ActionsCreators from '../../redux/actions/actionsCreators'
class MyAccount extends Component{
constructor(props){
super(props)
this.state = {
unit: '',
timezone: '',
test:''
}
}
componentDidMount(){
this.setState({
unit: this.props.auth.user.unit,
timezone: this.props.auth.user.timezone,
test:'test'
})
}
render(){
return(
<div>
<h1>MyAccount</h1>
<span>state {JSON.stringify(this.state)}</span>
<br/>
<span>props unit:{JSON.stringify(this.props.auth.user.unit)} </span>
<br />
<span>props timezone:{JSON.stringify(this.props.auth.user.timezone)} </span>
</div>
)
}
}
const mapStateToProps = state => {
return {
auth: state.auth
}
}
const mapDispatchToProps = dispatch => {
return{
updateProfile: (user) => dispatch(ActionsCreators.updateProfileRequest(user))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MyAccount)
我的猜测是,当您刷新页面时,您的组件会在 之前 加载您的 redux 状态。因此,当 componentDidMount
触发时,没有任何内容redux,所以道具是零。当 redux 最终填充时,它会重新渲染,导致 props 出现在组件中。我建议看一下 getDerivedStateFromProps
(它取代了 React 16.3 中旧的 componentWillReceiveProps
生命周期事件)。您可以使用它来设置新道具进入时的状态。在您的组件中删除这样的东西应该有效:
static getDerivedStateFromProps(nextProps, prevState){
if(nextProps.someValue!==prevState.someValue){
return { someState: nextProps.someValue};
}
else return null;
}
这个例子是从 this article 中提取的,我发现它是关于这个新的 React 事件如何工作的很好的入门。
您可以使用shouldComponentUpdate
跟踪道具的变化并相应地更新状态
shouldComponentUpdate(nextProps, nextState) {
return (nextProps.auth !== this.props.auth ||
nextState.unit !== this.state.unit ||
nextState.timezone !== this.state.timezome);
}
componentDidUpdate(prevProps) {
if (prevProps.auth !== this.props.auth) {
this.setState({
unit: this.props.auth.user.unit,
timezone: this.props.auth.user.timezone
});
}
}
这样,如果道具在 componentDidMount
之后到达,状态将被更新
希望它有用,试试这个...
import _isEqual from 'lodash/isEqual';
componentWillReceiveProps(nextProps) {
if(!_isEqual(this.props.auth.user, nextProps.auth.user)){
this.setState({
unit: this.props.auth.user.unit,
timezone: this.props.auth.user.timezone,
test:'test'
})
}
}
我有一个问题,但我找不到原因,我相信这与我缺乏反应经验有关,那我们走吧。当组件被安装时,componentDIdMount 被调用并插入道具的状态,但是当我刷新页面(f5)时,单位和时区状态没有收到 didMount 的值,但是状态测试收到它的值,它是好像 this.pros 在 componentDidMount 中不存在但它在组件上。
When the component is rendered.
When refresh to page (f5).
我看到刷新时调用了componentDidMount,因为测试插入状态,但是this.props不是。有人把灯指向隧道尽头吗?
My component.
import React, {Component} from 'react'
import { connect } from 'react-redux';
import ActionsCreators from '../../redux/actions/actionsCreators'
class MyAccount extends Component{
constructor(props){
super(props)
this.state = {
unit: '',
timezone: '',
test:''
}
}
componentDidMount(){
this.setState({
unit: this.props.auth.user.unit,
timezone: this.props.auth.user.timezone,
test:'test'
})
}
render(){
return(
<div>
<h1>MyAccount</h1>
<span>state {JSON.stringify(this.state)}</span>
<br/>
<span>props unit:{JSON.stringify(this.props.auth.user.unit)} </span>
<br />
<span>props timezone:{JSON.stringify(this.props.auth.user.timezone)} </span>
</div>
)
}
}
const mapStateToProps = state => {
return {
auth: state.auth
}
}
const mapDispatchToProps = dispatch => {
return{
updateProfile: (user) => dispatch(ActionsCreators.updateProfileRequest(user))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MyAccount)
我的猜测是,当您刷新页面时,您的组件会在 之前 加载您的 redux 状态。因此,当 componentDidMount
触发时,没有任何内容redux,所以道具是零。当 redux 最终填充时,它会重新渲染,导致 props 出现在组件中。我建议看一下 getDerivedStateFromProps
(它取代了 React 16.3 中旧的 componentWillReceiveProps
生命周期事件)。您可以使用它来设置新道具进入时的状态。在您的组件中删除这样的东西应该有效:
static getDerivedStateFromProps(nextProps, prevState){
if(nextProps.someValue!==prevState.someValue){
return { someState: nextProps.someValue};
}
else return null;
}
这个例子是从 this article 中提取的,我发现它是关于这个新的 React 事件如何工作的很好的入门。
您可以使用shouldComponentUpdate
跟踪道具的变化并相应地更新状态
shouldComponentUpdate(nextProps, nextState) {
return (nextProps.auth !== this.props.auth ||
nextState.unit !== this.state.unit ||
nextState.timezone !== this.state.timezome);
}
componentDidUpdate(prevProps) {
if (prevProps.auth !== this.props.auth) {
this.setState({
unit: this.props.auth.user.unit,
timezone: this.props.auth.user.timezone
});
}
}
这样,如果道具在 componentDidMount
之后到达,状态将被更新
希望它有用,试试这个...
import _isEqual from 'lodash/isEqual';
componentWillReceiveProps(nextProps) {
if(!_isEqual(this.props.auth.user, nextProps.auth.user)){
this.setState({
unit: this.props.auth.user.unit,
timezone: this.props.auth.user.timezone,
test:'test'
})
}
}