2017-04-26 119 views
1

我的React组件需要ajax调用来获取数据以呈现其本身。使用React和react-router进行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的阵营文档阅读后,我担心在渲染调用改变卖场,甚至异步一点。

我想出了另一种使用componentDidMount和componentDidUpdate的方法。这最终会稍微复杂一点,因为组件最初呈现时,componentDidMount和componentDidUpdate都会被调用。任何后续更新(通过URL被更改,然后通过反应路由器重新渲染)而不是调用componentDidMount,而只是componentDidUpdate(它也在初始安装期间被调用)。为了避免任何不必要的渲染,需要小心注意标志。

这第二种方法似乎更复杂,涉及到更多的功能覆盖...

所以,问题是:有什么不对的渲染功能内发射了一个Ajax请求?

感谢...

回答

0

render功能应该是pure。这意味着在render中进行AJAX调用是严格禁止的。原因是如果你的渲染函数可以改变状态,它也会导致重新渲染,并且这可能会导致你被困在一个渲染循环中,这将被调试。

但是,即使你仔细写你render功能,让你确信你能永远不会停留在一个渲染循环,也有深层次原因,以保持render纯:阵营预计render是纯粹的,所以它是不在处理渲染时期待状态更改。尽管您需要检查React的内部结构,但我非常肯定地改变状态,而渲染将会对渲染性能产生严重影响,因为如果状态在渲染时发生变化,它需要React中止渲染并重新启动。

+0

感谢您的回复。我只是困惑,因为渲染本身没有改变状态。直到ajax调用完成,状态才被更新,这是在渲染函数干净完成后的很长一段时间。 随着我设置的标志,渲染只被调用两次。一次用于加载视图,并在数据返回后再次加载。没有循环发生。 – Marc

+0

即使是异步的,您也不应该在'render'中启动任何副作用,因为这是React运行时期望您做的事情,您应该假设运行时已针对该用例进行了优化。即使它现在可以工作,它也可能在未来的React版本中崩溃。 –