Как бороться с зависимостями данных в компоненте - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть компонент, который отображает список Project .Я получаю данные с сервера в componentDidMount () .В редукторе я выбираю первый элемент, устанавливая переменную 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 () , я пытаюсь получить данные, только если переменная установлена, но мой компонент никогда не отображается снова.Я что-то упустил, но что?

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Я думаю, что теперь я немного лучше понимаю вопрос, поэтому вот как я это сделаю: вместо проверки, существует ли currentProject в компоненте Tasks, почему бы не проверить его и условно не отобразить Tasks вProjects компонент?Что-то вроде:

...
<div>
  { this.props.currentProject && <Tasks /> }
</div>
...

Таким образом, задачи не отображаются / не монтируются, пока не заполнится this.props.currentProject, что делает проверку в componentDidMount избыточной и позволяет вам извлекать задачи без проверки.

0 голосов
/ 25 сентября 2018

Вам нужно будет связать 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.Диспетчерские вызовы предназначены для обработки данных, возвращаемых при вызове.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...