我有一个显示项目列表的组件。我正在 componentDidMount()中从服务器获取数据。在reducer中,我选择第一项,设置一个 currentProject 变量。我想显示与此项目相关的任务。如何在获取任务之前确保已设置此变量?
项目
class Projects extends React.Component {
constructor(props) {
super(props);
this.selectProject = this.selectProject.bind(this);
}
componentDidMount() {
const { fetchByUserId, user } = this.props;
fetchByUserId(user.id);
}
selectProject(e, project) {
e.preventDefault();
const { select } = this.props;
select(project.id);
}
render() {
const { items } = this.props;
return (
<div>
<div className="projects">
<ul>
{_.map(items, (project) => (
<li key={project.id} onClick={(e) => this.selectProject(e, project)}>
{project.title}
</li>
))}
</ul>
</div>
<div className="tasks">
<Tasks />
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
const { user } = state.authentication;
const { items, loading, error } = state.projects;
return {
user,
items,
loading,
error
};
};
export default connect(
mapStateToProps,
{
fetchByUserId: projectsActions.fetchByUserId,
select: projectsActions.select
}
)(Projects);
任务
class Tasks extends React.Component {
componentDidMount() {
const { fetchTasksByProjectId, currentProject } = this.props;
if (currentProject) {
fetchTasksByProjectId(currentProject.id);
}
}
renderTasks(tasks) {
return (
<div>
{_.map(tasks, (task) => (
<strong>{task.name}</strong>{" "}
{task.description}
))}
</div>
);
}
render() {
const { currentProject, tasks } = this.props;
if (!tasks.length) {
return <div>Loading...</div>;
}
return (
<div>
<h1 className="title">{currentProject.title}</h1>
{this.renderTasks(tasks[currentProject.id])}
</div>
);
}
}
const mapStateToProps = (state) => {
const { current: currentProject } = state.projects;
const { items: tasks } = state.tasks;
return {
currentProject,
tasks
};
};
export default connect(
mapStateToProps,
{
fetchTasksByProjectId: tasksActions.fetchByProjectId
}
)(Tasks);
在任务 componentDidMount()中,我试图仅在设置了变量的情况下获取数据,但我的组件永远不会再呈现。我想念什么,但是呢?
答案 0 :(得分:3)
您必须将fetchTasksByProjectId链接到fetchByUserId操作调用。
使用伪代码:
getProjectByUserId
.then(projects =>
getTasksByProjectId(projects[selectedProjectIndex])
)
.catch(error)
此外,从您的componentDidMount()中删除任务调用
//projects action call
export function getProjectByUserId(user_id) {
return async(dispatch, getState) => {
try {
let projects = await projectsService.getProjectByUserId(user_id);
dispatch({ type: "FETCH_PROJECTS", projects});
/*Notice the call to another action in the response of the first action call, fyi the getState is used to access the id of current project in your redux state*/
dispatch(getTasksByProjectId(projects[getState.currentProject.id]));
}
catch (error) {
return error;
}
};
}
//Tasks action call
export function getTasksByProjectId(project_id) {
return async(dispatch, getState) => {
try {
const tasksData = await projectsService.getTasksByProjectId(project_id);
dispatch({ type: "FETCH_CURRENT_TASKS", tasksData});
}
catch (error) {
return error;
}
};
}
更详细的示例,可以更好地理解操作文件。这些服务是具有实际get请求的文件。调度调用将处理从调用返回的数据。
答案 1 :(得分:1)
我想我现在对问题的理解要好一些了,因此,我将按照以下方法做:不检查currentProject
组件中是否存在Tasks
,为什么不检查它并有条件地渲染{ Tasks
组件中的{1}}?像这样:
Projects
这样,在填充...
<div>
{ this.props.currentProject && <Tasks /> }
</div>
...
之前,不会渲染/挂载Tasks,从而使this.props.currentProject
中的检查变得多余,并允许您在不检查的情况下提取任务。