у моей проблемы есть обходной путь, но меня интересует основная проблема.
В моем компоненте 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 всегда перед первым рендером!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это ожидаемое (правильное) поведение, вы можете сослаться на эту диаграмму жизненного цикла здесь.
Сначала запускается функция конструктора, затем функция рендеринга, затем componentDidMount.
И согласно документу реакции компонентдидмаунт:
«Вы можете вызвать setState() немедленно в componentDidMount(). Это вызовет дополнительный рендеринг, но это произойдет до того, как браузер обновит экран. Это гарантирует, что даже если в этом случае render() будет вызываться дважды… "
Наличие избыточной отправки действия в componentDidMount также будет действовать как setState и запускать дополнительный рендеринг. Я хотел бы спросить, хотя, что именно вы пытаетесь сделать? потому что я не нахожу это поведение странным или странным вообще
мой плохой, я думал, что componenetDidMount всегда срабатывает перед первоначальным рендерингом.
componentDidMount запускается только после первоначального рендеринга, и это не будет иметь никакого значения, даже если вы используете в нем асинхронное ожидание.