【问题标题】:Best practice for making an ajax call using React and react-router使用 React 和 react-router 进行 ajax 调用的最佳实践
【发布时间】:2017-09-24 05:51:49
【问题描述】:

我的 React 组件需要一个 ajax 调用来获取数据来呈现自己。

最初,我使用该方法在渲染中启动 ajax 调用。这是我的伪代码...

export class MyView extends React.Component<any, any> {

    hasAjaxData: boolean = false;

    renderAndGetData() {
        const data = {

        };

        AjaxCall(data)
            .then((results) => {
                this.hasAjaxData = true;
                // save to store here, causing a rerender
                ...
                });
            })
            .catch((err: Error) => {
                console.error(err);
            });
        return (
            <SpinnerComponent />
        );
    }

    renderWithData() {
        return (
            <div>
                Render with data here
            </div>
        );
    }

    render() {
        return this.hasAjaxData ? this.renderWithData() : this.renderAndGetData();
    }
}

在阅读了有关 render call 的 React 文档后,我有点担心在渲染调用中更改存储,即使是异步的。

我想出了另一种使用 componentDidMount 和 componentDidUpdate 的方法。这最终会稍微复杂一些,因为在最初渲染组件时,componentDidMount 和 componentDidUpdate 都会被调用。任何后续更新(通过更改 URL,然后通过 react-router 重新渲染)都调用 componentDidMount,而只是调用 componentDidUpdate,(在初始挂载期间也会调用)。为避免任何不必要的渲染,需要特别注意标志。

第二种方法似乎更复杂,涉及更多的函数覆盖......

所以问题是:从渲染函数中触发 ajax 请求有什么问题吗?

谢谢...

【问题讨论】:

    标签: ajax reactjs react-router


    【解决方案1】:

    render 函数应该是 pure。这意味着在render 中进行AJAX 调用是严格禁止的。这样做的原因是,如果你的渲染函数可以改变状态,它也会导致重新渲染,这可能会导致你陷入渲染循环,这将是调试的地狱。

    但是,即使您仔细编写 render 函数,以确保您永远不会陷入渲染循环,还有更多理由保持 render 纯:React 期望 render 是纯的,因此它在处理渲染时不期望状态更改。尽管您需要检查 React 的内部结构以确定,但我很确定在渲染时更改状态将对渲染性能产生严重影响,因为如果在渲染时状态发生更改,它将要求 React 中止渲染并重新启动。

    【讨论】:

    • 感谢您的回复。我只是感到困惑,因为渲染本身没有任何改变状态。直到 ajax 调用完成才更新状态,这是在渲染函数干净地完成之后很久。使用我设置的标志,render 只被调用两次。一次用于加载视图,并在返回数据后再次。没有循环发生。
    • 即使是异步的,您也不应该在render 中启动任何副作用,因为这是 React 运行时希望您执行的操作,您应该假设运行时针对该用例进行了优化。即使它现在可以工作,它也可能会在未来的 React 版本中中断。
    猜你喜欢
    • 2016-11-16
    • 2021-10-30
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    • 2016-05-02
    • 2019-02-19
    • 2016-07-25
    • 1970-01-01
    相关资源
    最近更新 更多