getDerivedStateFromProps对我的应用程序不起作用。如何替换componentWillRecieveProps?

时间:2018-07-11 17:52:43

标签: reactjs redux react-lifecycle getderivedstatefromprops

我正在使用Redux创建一个React应用程序,并且在我的“帐户设置”页面上,我有一个表格要预先填充用户的信息,然后使他们能够编辑字段并更新其个人资料。我的代码如下:

class UpdateProfile extends Component {
  constructor(props) {
    super(props);
    this.props.getCurrentProfile();
    this.state = {
      firstName: "",
      lastName: "",
      email: "",
      gender: "",
      bday: "",
      address1: "",
      address2: "",
      zipCode: "",
      phone: "",
      contactMethod: "",
      plan: "",
      apptReminders: true,
      updates: true,
      errors: {}
    };

    // Bind functions
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  // static getDerivedStateFromProps(nextProps) {
  //   if (nextProps.profile) {
  //     let personal = nextProps.profile.profile.personalInfo;
  //     let account = nextProps.profile.profile.accountInfo;
  //     return {
  //       firstName: personal.firstName,
  //       lastName: personal.lastName,
  //       email: personal.email,
  //       address1: personal.address1,
  //       address2: personal.address2,
  //       zipCode: personal.zipCode,
  //       phone: personal.phone,
  //       contactMethod: account.contactMethod,
  //       plan: account.plan,
  //       apptReminders: account.alerts.apptReminders,
  //       updates: account.alerts.updates
  //     };
  //   } else {
  //     return null;
  //   }
  // }

  componentWillReceiveProps(nextProps) {
    if (nextProps) {
      let personal = nextProps.profile.profile.personalInfo;
      let account = nextProps.profile.profile.accountInfo;
      this.setState({
        firstName: personal.firstName,
        lastName: personal.lastName,
        email: personal.email,
        address1: personal.address1,
        address2: personal.address2,
        zipCode: personal.zipCode,
        phone: personal.phone,
        contactMethod: account.contactMethod,
        plan: account.plan,
        apptReminders: account.alerts.apptReminders,
        updates: account.alerts.updates
      });
    }
  }

this.props.getCurrentProfile()将axios请求发送到mongoDB并接收当前用户的配置文件。

问题是,如果我使用getDerivedStateFromProps方法,则文本字段是静态的,无法进行编辑。即使使用componentWillMount方法,如果从浏览器刷新页面并说配置文件为空,也会出现错误。

我对React和生命周期方法非常陌生,非常感谢任何关于我做错了事情以及不赞成componentWillReceiveProps的反馈。

预先感谢

2 个答案:

答案 0 :(得分:0)

在进一步阅读了生命周期方法之后,我想到了这个解决方案:

 // Get profile
  componentDidMount() {
    this.props.getCurrentProfile();
  }

  // Fill in form
  componentDidUpdate(prevProps) {
    if (
      this.props.profile.profile &&
      prevProps.profile.profile !== this.props.profile.profile
    ) {
      let personal = this.props.profile.profile.personalInfo;
      let account = this.props.profile.profile.accountInfo;
      this.setState({
        firstName: personal.firstName,
        lastName: personal.lastName,
        email: personal.email,
        address1: personal.address1,
        address2: personal.address2,
        zipCode: personal.zipCode,
        phone: personal.phone,
        contactMethod: account.contactMethod,
        plan: account.plan
      });
    }
  }

尽管可以渲染两次,但仍可以根据需要运行。如果有人知道等到请求返回呈现的方法,我将不胜感激。仅供参考,我正在使用Redux

答案 1 :(得分:0)

我看不到您在此应用程序中使用redux的地方.redux存储应该是真实的单一来源,并且您不应该使用本地状态来管理帐户。

此外,redux并非用于异步操作,axios是异步的,您需要使用thunk之类的中间件,以便您的操作可以返回一个函数而不只是一个类型。然后,您可以从返回的异步调用中调用调度,这将更新您的商店。

我建议开始:https://redux.js.org/introduction 然后前进到异步操作:https://redux.js.org/advanced/async-actions

当我开始学习本教程时,对我来说最有意义:https://codepen.io/stowball/post/a-dummy-s-guide-to-redux-and-thunk-in-react

//Example of asyn call in redux with thunk      
function fetchPosts(subreddit){
      //Thunk middleware knows how to handle functions.
      //It passes the dispatch method as an argument to the function,
      //thus making it able to dispatch actions itself.

    return dispatch =>{
            dispatch(requestPosts(subreddit))        
        return axios.get(`https://www.reddit.com/r/${subreddit}.json`,{headers: { 'Content-Type': 'text/plain;charset=utf-8'}})
        .then( res =>{                 
            dispatch(receivePosts(subreddit,res.data))
        }).catch(error=>{
            console.log(error);
        })
    }
  }