Рендеринг, кажется, запускается до componentDidMount (используется async/await)

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

В моем компоненте 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.info(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 равными им.

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

Shubham Khatri 19.02.2019 06:31

это очень интересно, у меня долгое время было неправильное восприятие componentDidMount всегда перед первым рендером!

Acy 19.02.2019 15:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
459
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

И согласно документу реакции компонентдидмаунт:

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

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

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

Acy 19.02.2019 15:55

Другие вопросы по теме