【问题标题】:render seems to be triggering before componentDidMount (async/await used)渲染似乎在 componentDidMount 之前触发(使用了异步/等待)
【发布时间】:2019-02-19 03:41:14
【问题描述】:

我的问题确实有解决方法,但我对潜在问题感兴趣。

在我的组件 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 也不会调用任何错误。

这是我如何获取数据的代码: 在我的组件“AuthorProfile”的 componentDidMount 中:

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

这将触发一个 redux 操作 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.....,) 更新我的 redux 状态,调度看起来像这样:

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

我最终将使用这个 other_author_created 路线图数据并将我的 displayData 设置为等于它。

【问题讨论】:

  • componentDidMount 仅在初始渲染后触发,即使您在其中使用 async await 也不会产生任何影响
  • 这很有趣,很长一段时间我在第一次渲染之前总是对componentDidMount有错误的认识!

标签: javascript reactjs asynchronous axios


【解决方案1】:

这是预期(正确)的行为,您可以参考此生命周期图here

先运行构造函数,再运行render函数,再运行componentDidMount。

并根据反应文档componentDidMount

"你可以在 componentDidMount() 中立即调用 setState()。它会触发额外的渲染,但它会在浏览器更新屏幕之前发生。这样可以保证即使在这种情况下会调用两次 render() ……”

【讨论】:

    【解决方案2】:

    让 redux 在 componentDidMount 中调度一个动作也会像 setState 一样触发额外的渲染。不过我会问,你到底想做什么?因为我根本不觉得这种行为奇怪或奇怪

    【讨论】:

    • 我的错,认为 componenetDidMount 总是在初始渲染之前触发。
    猜你喜欢
    • 2018-05-02
    • 2018-04-05
    • 2019-02-10
    • 2016-03-12
    • 1970-01-01
    • 2018-09-03
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多