通过 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'
        })
}
}