【问题标题】:Correct approach for using flux and component lifecycle使用助焊剂和组件生命周期的正确方法
【发布时间】:2018-08-11 00:57:06
【问题描述】:

我正在从CodePen 上看到的内容迁移代码。

IssueBox 中,我计划实现一个表单,最终用户将更新该表单,将状态从“未验证”设置为“已验证”。

App(错误重命名此组件)将是我的父母,IssueBox 将是孩子。

所以我通过了flux => Action -> dispatcher -> udpate db -> update view。

现在我有了新的状态并且应该更新视图,我是否使用 componentWillRecieveProps() 然后在那里设置状态,以便在 IssueBox 中我可以继续使用 this.props 从而依次更新它。

import React, { Component } from "react";
  import IssueBox from "./issuebox.js";
  import "./App.css";

  class App extends Component {
    constructor(props) {
      super(props);

      this.state = {
        isLoaded: false,
        email: [],
        counter: 0,
        title: "Test run"
      };
    }

    componentDidMount() {

      fetch(
        "https://s3-us-west-2.amazonaws.com/s.cdpn.io/311743/dummy-emails.json"
      )
        .then(res => res.json())
        .then(result => {
          const emails = result.data;
          console.log("resutl state: ", emails);
          let id = 0;
          for (const email of emails) {
            email.id = id++;
            email.verified = 'False'
          }
          this.setState({
            isLoaded: true,
            emails: emails
          });
        });
    }
    render() {
      //console.log(this.state.email);
      return (
        <div className="App">
          <div>
            <IssueBox emails={this.state.email} />
          </div>
        </div>
      );
    }
  }


  //issuebox.js

  import React, { Component } from "react";

  class IssueBox extends Component {
    constructor(args) {
      super(args);

      const emails = this.props.emails;
      console.log("inner props: ", emails);
      let id = 0;
      for (const email of emails) {
        email.id = id++;
      }

      this.state = {
        selectedEmailId: 0,
        currentSection: "inbox",
        emails
      };
    }

//...从 codepen 复制和粘贴

setSidebarSection(section) {
  let selectedEmailId = this.state.selectedEmailId;
  if (section !== this.state.currentSection) {
    selectedEmailId = "";
  }

  this.setState({
    currentSection: section,
    selectedEmailId
  });
}

componentWillReceiveProps(newProps) {
  // Assign unique IDs to the emails

  this.setState({ emails: newProps.data });
}

render() {
  const currentEmail = this.state.emails.find(
    x => x.id === this.state.selectedEmailId
  );
  return (
    <div>
      <Sidebar
        emails={this.props.emails}
        setSidebarSection={section => {
          this.setSidebarSection(section);
        }}
      />
    )}

  ///.....copy and pase from codepen

【问题讨论】:

    标签: reactjs flux


    【解决方案1】:

    错误是由componentWillReceiveProps()中的这一行引起的:

    this.setState({ emails: newProps.data });

    电子邮件来自一个名为emails 的属性,因此该行应该是:

    this.setState({ emails: newProps.emails });

    话虽如此,componentWillReceiveProps()gets called more frequently than you might expect。我建议您将id 添加到AppcomponentDidMount() 内的电子邮件中,以便它们进入IssueBox 以供使用。这意味着App 将电子邮件保持在其状态,并简单地将它们作为道具传递给IssueBox,因此您可以从IssueBox 的状态中删除emails,并且只需使用通过道具进入的电子邮件无处不在在IssueBox 内(类似于其他组件如何使用emails 进入它们的道具并且不让它们保持在自己的本地状态)。

    【讨论】:

    • 嗨,Brian,谢谢你的建议,我按照你说的做了,而且成功了。所以,现在我有一个后续问题,我应该使用哪个生命周期钩子。应该ComponentUpdate 还是我可以使用forceUpdate? SideView 中的这些项目的状态将从“未验证”更新为已验证。
    • codepen 中采用的方法很好。所有的数据都存在于 App 的状态中,并作为 props 传递给无状态的子组件。如果子组件需要对数据做一些事情(比如从“未验证”更改为“已验证”),那么 App 会在他们的 props 中传递回调,他们可以调用这些回调来改变 App 中的状态。然后他们简单地渲染他们在道具中给出的东西。每当 App 中的状态发生变化时,它们都会自动获取更新的道具并重新渲染。 App 中状态数据的初始加载可以像你一样在 componentDidMount 中完成。
    猜你喜欢
    • 1970-01-01
    • 2015-03-22
    • 2020-02-29
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 1970-01-01
    相关资源
    最近更新 更多