рендеринг, кажется, срабатывает до того, как componentDidMount (используется async / await) - PullRequest
0 голосов
/ 19 февраля 2019

В моей проблеме есть обходной путь, но меня интересует основная проблема.

В моем компоненте AuthorProfile я использую async / await для извлечения данных, затем устанавливаю свое состояние для извлеченных данных и использую консольный журнал в render (), чтобы увидеть, что происходит, вот мой компонент безфункция рендеринга:

  constructor(props) {
    super(props);
    this.state = { displayData: [] };
  }
  async componentDidMount() {
    await this.props.getRoadmapByUser({
      user_id: this.props.location.pathname.slice(9)
    });
    this.setState({
      displayData: this.props.auth.other_author_created_roadmaps
    });

  }

При рендеринге у меня есть return(blah blah blah... {console.log(this.state.displayData)}, , когда я загружаю свою страницу, моя консоль всегда будет печатать пустые строки примерно 2 раза (так как это было мое состояние displayData вначале), а затем начинает регистрировать извлеченные данные .Этого не должно быть, я использовал async / await.Мой быстрый обходной путь прост для моего приложения, я пытаюсь отобразить список, который будет использовать .map, я инициировал displayData в пустой массив, чтобы даже при отсутствии данных .map не вызывал никаких ошибок.

Вот мой код о том, как я извлек данные: В componentDidMount моего компонента AuthorProfile:

 async componentDidMount() {
    await this.props.getRoadmapByUser({
      user_id: this.props.location.pathname.slice(9)
    });
  }

Это вызовет редукционное действие getRoadmapByUser, которое выглядит следующим образом:

 export const getRoadmapByUser = id => dispatch => {
   return axios
    .post("/api/users/getroadmapbyuser", id)
    .then(res => dispatch({ type: GET_ROADMAPS_BY_USER, payload: res.data }));
};

Это делает вызов API, а затем использует данные, полученные из вызова API, для отправки, вот вызов post / api / users / getroadmapbyuser:

router.post("/getroadmapbyuser", (req, res) => {
  User.findOne({ _id: req.body.user_id }).then(user =>
    res.json(user.createdRoadmap)
  );
});

Это вернетполе в моей базе данных, теперь я собираюсь обновить свое состояние редукса с помощью .then (res => dispatch .....,), отправка выглядит так:

 case GET_ROADMAPS_BY_USER:
  return {
    ...state,
    other_author_created_roadmaps: action.payload
  };

Я буду, наконец, использоватьэти other_author_created данные дорожных карт и установить мои displayData равным ему.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

При наличии избыточной диспетчеризации действие в componentDidMount также действует как setState и запускает дополнительный рендеринг.Я бы спросил, что именно вы пытаетесь сделать?потому что я не нахожу это поведение странным или странным вообще

0 голосов
/ 19 февраля 2019

Это ожидаемое (правильное) поведение, вы можете сослаться на эту диаграмму жизненного цикла здесь

Сначала выполняется функция конструктора, затем функция визуализации, затем componentDidMount.

И согласно реагирующему документу componentDidMount :

"Вы можете немедленно вызвать setState () в componentDidMount (). Это вызовет дополнительный рендеринг, но это произойдет до того, как браузер обновит экран.Это гарантирует, что даже если render () будет вызываться дважды в этом случае ... "

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