在 componentDidMount() 之前调用 React render()

IT技术 javascript reactjs
2021-04-01 06:36:15

在我componentDidMount()的 API 调用中,我调用了一些数据,然后这个调用设置了一个我在渲染中使用的状态对象。

componentDidMount() {
            const { actions } = this.props;

            this.increase = this.increase.bind(this);

            // api call from the saga
            actions.surveyAnswersRequest();

            // set breadcrumb
            actions.setBreadcrumb([{ title: 'Score' }]);
            actions.setTitle('Score');
            this.increase();
        }

在我的渲染函数中,我将一些 prop 值传递到视图文件中:

render() {
        const { global, gallery, survey_answers, survey, survey_actual_answers } = this.props;

        if (global.isFetching) {
            return <Loading />;
        }
        return this.view({ gallery, survey_answers, survey, survey_actual_answers });
    }

我遇到的问题是survey_actual_answers在第一次加载页面时没有设置 prop,但是当我刷新页面时,prop 返回的数据很好,脚本的其余部分将运行。这只是第一次为该 prop 值返回一个空数组。

这是我传递props的方式:

Score.propTypes = {
    actions: PropTypes.object.isRequired,
    global: PropTypes.object.isRequired,
    survey: PropTypes.object.isRequired,
    survey_answers: PropTypes.object.isRequired,
    gallery: PropTypes.object.isRequired,
    survey_actual_answers: PropTypes.array.isRequired,
    survey_score_system: PropTypes.array.isRequired,
    survey_styles: PropTypes.object.isRequired,
    survey_general_doc_data: PropTypes.object.isRequired
};

function mapStateToProps(state, ownProps) {
    return {
        ...ownProps,
        global: state.global,
        gallery: state.gallery,
        survey: state.survey,
        survey_actual_answers: state.survey.survey_actual_answers,
        survey_answers: state.survey.survey_answers,
        survey_score_system: state.survey.survey_score_system,
        survey_styles: state.survey.survey_styles,
        survey_general_doc_data: state.survey.survey_general_doc_data,
        isFetching: state.isFetching
    };
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators({
            ...globalActions,
            ...galleryActions,
            ...surveyActions
        }, dispatch)
    };
}

有谁知道为什么会这样?就好像它根本没有调用 componentDidMount 一样。

3个回答

之所以会发生这种情况,是因为 React 从根本上是如何工作的。React 应该让人感觉快速、流畅和活泼;应用程序永远不应该被 http 请求或异步代码阻塞。答案是使用生命周期方法来控制 DOM。

组件挂载是什么意思?

更好地理解一些 React 词汇可能会有所帮助。当一个组件被挂载时,它被插入到 DOM 中。这是调用构造函数的时候。componentWillMount 几乎是构造函数的同义词,并且大约在同一时间被调用。componentDidMount 只会在第一次渲染后被调用一次。

componentWillMount -->渲染--> componentDidMount

这与重新渲染或更新有何不同?

现在组件位于 DOM 中,您想要更改显示的数据。当调用 setState 或从父组件传递新的 props 时,将发生组件更新。

componentWillRecieveProps --> shouldComponentUpdate --> componentWillUpdate
-->渲染--> componentDidUpdate

值得注意的是,http 请求通常在 componentDidMount 和 componentDidUpdate 中完成,因为我们可以在这些地方使用 setState 触发重新渲染。

那么如何在渲染发生之前获取数据呢?

嗯,人们有几种方法可以解决这个问题。第一个是在您的组件中设置一个初始状态,以确保如果来自 http 请求的数据尚未到达,它不会破坏您的应用程序。它将使用默认或空状态,直到 http 请求完成。

我通常不喜欢有一个加载模式,但有时它是必要的。例如,当用户登录时,在他们完成身份验证之前,您不希望将他们带到站点的受保护区域。我尝试做的是在用户登录到前端时使用该加载模式,在不影响用户体验的情况下加载尽可能多的数据。

您还可以使组件显示为正在加载,同时不影响站点其余部分的用户体验。我最喜欢的例子之一是Airbnb 网站请注意,该站点的大部分内容都可以使用,可以滚动,单击链接,但是“体验”下的区域处于加载状态。这是使用 React 的正确方法,也是 setState 和 HTTP 请求在 componentDidMount/componentDidUpdate 中完成的原因。

真的很棒的答案 - 这让我看到了 React.Component 文档。2021 年,componentWillMount() 被认为是不安全的。但重要的部分是渲染发生在 componentDidMount 之前!
2021-06-14 06:36:15

在 componentdidmount 中使用 setState。这是我的代码:

 async componentDidMount() {

    danhSachMon = await this.getDanhSachMon();
    danhSachMon=JSON.parse(danhSachMon);
    this.setState(danhSachMon);
}

render() {
    return (
        <View>
            <FlatList
                data={danhSachMon}
                showsVerticalScrollIndicator={false}
                renderItem={({ item }) =>
                    <View >
                        <Text>{item.title}</Text>
                    </View>
                }
                keyExtractor={(item, index) => index.toString()}
            />
        </View>
    )
}

不推荐使用 componentWillMount。现在您需要使用“DidMount”,一旦它完成并在渲染时更改 DOM,react 将处理其他所有事情。

确保在渲染中更新并使用正确的变量/状态/props。

componentDidMount() {    
    const { applicationId } = this.props;
    if (applicationId) {
      ApplicationService.getQuotesByApplicationId(applicationId).then((response) => {
        const quotes = _.get(response, 'data.data');
        this.setState({
          quotes,
        });
      });

    ....

    }

    render() {

        const quotes = _.get(this.state, 'quotes', null);
        return (
          <div className="application">
            <h4 className="application__sub">Application</h4>
            <h1 className="application__title">Quote Comparison</h1>
            <div className="form-wrapper">
              {this.renderQuotes(quotes)}
            </div>
            <div />
          </div>
        );
      }

在这里,我从 API 获取引号,一旦它完成,它就会在状态中设置一个变量,然后渲染和react就会开始工作。