渲染组件后更新本地状态

时间:2019-06-14 01:47:04

标签: reactjs firebase redux

我正在使用React,Redux和Firebase创建一个项目计划应用程序。我的Firestore数据库中的单个项目记录包含一个标题和一些内容。当我更新项目时,我将输入字段的defaultValues设置为要编辑的项目的正确数据。但是,仅当我对“内容”和“标题”输入字段都进行了更改时,更新才有效。否则,提交这些值后,数据将被删除,因为本地状态没有任何变化,因此将未修改的字段更新为空字符串:“”

我尝试在render方法中设置EditProject组件的本地状态,但这是不可能的:

render() {
    const { project, auth } = this.props;
    if (!auth.uid) return <Redirect to="/signin" />;
    if (project) {
      this.setState({
        title: project.title,
        content: project.content
      });

...

我也尝试过在componentDidMount期间设置状态,例如:

  componentDidMount = () =>{
    const { project } = this.props;
    this.setState({
      title: project.title,
      content: project.content
    })
  }

但是问题在于,mapStateToProps之前的componentDidMount无法映射项目道具

最后,我尝试从父组件projectDetails传递项目支持,但我无法成功完成。我可能在这部分做错了,所以请告诉我是否有使用我所拥有代码的好的方法。在ProjectDetails中:

<Link to={"/edit/" + docId} key={docId}>
  <button className="btn pink lighten-1 z-depth-0">Edit</button>
</Link>

这链接到我要修复的“损坏的” EditDetails组件。


这是我的EditProject组件代码

class EditProject extends Component {
  state = {
    title: "",
    content: ""
  };

  handleChange = e => {
    this.setState({
      [e.target.id]: e.target.value
    });
  };

  handleSubmit = e => {
    e.preventDefault();
    let localProject = this.state;
    let docId = this.props.docId;
    this.props.editProject(localProject, docId);
    const projectDetailURL = "/project/" + docId;
    this.props.history.push(projectDetailURL);
  };

  render() {
    const { project, auth } = this.props;
    if (!auth.uid) return <Redirect to="/signin" />;
    if (project) {
      return (
        <div className="container section project-details">
          <div className="card z-depth-0">
            <div className="card-content">
              <form onSubmit={this.handleSubmit} className="white">
                <h5 className="grey-text text-darken-3">Edit Project</h5>
                <div className="input-field">
                  <label htmlFor="title" className="active">
                    Title
                  </label>
                  <input
                    onChange={this.handleChange}
                    type="text"
                    id="title"
                    defaultValue={project.title}
                  />
                </div>
                <div className="input-field">
                  <label htmlFor="content" className="active">
                    Edit Project Content
                  </label>
                  <textarea
                    id="content"
                    onChange={this.handleChange}
                    className="materialize-textarea"
                    defaultValue={project.content}
                  />
                </div>
                <div className="input-field">
                  <button className="btn pink lighten-1 z-depth-0">
                    Update
                  </button>
                </div>
              </form>
            </div>
            <div className="card-action grey lighten-4 grey-text">
              <div>
                Posted by {project.authorFirstName} {project.authorLastName}
              </div>
              <div>{moment(project.createdAt.toDate()).calendar()}</div>
              <div className="right-align" />
            </div>
          </div>
        </div>
      );
    } else {
      return (
        <div className="container center">
          <p>Loading project...</p>
        </div>
      );
    }
  }
}

const mapStateToProps = (state, ownProps) => {
  //id = the document id of the project
  const id = ownProps.match.params.id;
  const projects = state.firestore.data.projects;
  const project = projects ? projects[id] : null;
  return {
    project: project,
    auth: state.firebase.auth,
    docId: id
  };
};

const mapDispatchToProps = dispatch => {
  return {
    editProject: (project, docId) => dispatch(editProject(project, docId))
  };
};

export default compose(
  connect(
    mapStateToProps,
    mapDispatchToProps
  ),
  firestoreConnect([
    {
      collection: "projects"
    }
  ])
)(EditProject);

在访问编辑页面后,如果用户不对输入字段进行任何更改,我希望数据保持不变。

1 个答案:

答案 0 :(得分:0)

通过使用React Router将道具从其“父组件”传递到我的EditProject组件,我能够正确地更新我的本地状态。我使用React路由器执行此操作,因为EditProject组件实际上并未嵌套在此“父组件”中。

以下是使用React Router将道具传递给其他组件的方法:

指定您要发送道具的位置以及要发送的内容:

precipIntensity


//ProjectDetails Component <Link to={{ pathname: "/edit/" + docId, state: { title: project.title, content: project.content } }}> <button className="btn">Edit</button> </Link> 生命周期方法中获取道具,并使用componentDidMount()更新本地状态。

setState()

我希望这会有所帮助!

相关问题