我正在使用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);
在访问编辑页面后,如果用户不对输入字段进行任何更改,我希望数据保持不变。
答案 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()
我希望这会有所帮助!