【问题标题】:React/redux: In which lifecycle methods is it allowed/forbidden/frowned upon/encouraged to dispatch actions? Why?React/redux:在哪些生命周期方法中允许/禁止/不赞成/鼓励调度操作?为什么?
【发布时间】:2017-11-29 14:00:11
【问题描述】:

在哪些反应生命周期方法 (https://facebook.github.io/react/docs/react-component.html) 中允许/禁止/推荐/不推荐调度 redux 操作?为什么?

假设我的无状态组件使用从服务器加载的数据,是否可以在 render() 期间调度操作以安排 ajax 调用?

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    答案是固执己见,但通常不受欢迎:生命周期方法被调用以响应组件树上的状态更改,但调度操作将可能启动另一个状态更改。这是 redux 试图避免的事件处理程序级联更新情况:您应该根据操作进行状态更改,而不是其他任何事情,否则您将拥有这些反应循环。状态变化是一次性发生的。

    实际上,为了方便起见,这条规则经常被放宽。所以没有真正的正确答案!就像软件开发中的大多数事情一样,它是微妙的。

    关于在渲染中不这样做(或任何不纯的东西)的其他答案是正确的:您想要的事件可能是“当这个组件被挂载时”与“每当它的渲染被调用时”这更好由constructor 处理或componentWillMount。此外,componentDidMount/componentWillUpdate/componentDidUpdate 更好地服务于您想要在渲染中完成的任何事情。

    【讨论】:

    • 是的,确实,我似乎也不清楚,为什么didComponentMount() 应该关心render() 使用什么(在从服务器加载内容的情况下)。我的意思是,这会导致逻辑重复,每当我更改render() 时,我需要更改didComponentMount(),需要确保两者一致。这是错误的来源。我看不到通过将 ajax 调用放入 didComponentMount() 获得什么,也许有可能将 ajax 请求处理到服务器?是的。一点都不简单。
    【解决方案2】:

    如果您正在谈论通过操作触发 ajax 调用,您应该使用componentDidMount,这是 facebook 明确推荐的,上面写着If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

    这是因为渲染组件可能比从服务器获取响应花费更多的时间,然后 ajax 回调触发了未安装组件的渲染。这是一个边缘案例,自从我使用 React 开发以来,我只发生过一次,但是为了安全起见,您应该在 componentDidMount 中触发 ajax 调用。

    如果您的 redux 操作只是对商店进行更改,那么您可以随时调度它。

    【讨论】:

    • "这是因为渲染一个组件可能比从服务器获得响应花费更多的时间,然后 ajax 回调触发了一个未安装组件的渲染。" - 这很有趣,什么你的意思是渲染一个组件可能需要更多时间?运行ReactDOM.render() ?所以你说ReactDOM.render() 在ajax 调用返回之后完成?但不是ReactDOM.render() 同步/阻塞吗?这样任何ajax调用的返回ReactDOM.render()实际上不能在ReactDOM.render()返回之前运行?我很迷惑。你能解释一下吗?
    • 我的理解是,如果 AJAX 调用在 render() 之前完成,那么它不会填充(初始)状态,此外,未安装组件上的异步 setState 既不会填充初始状态,也不会导致重新渲染,这就是不鼓励使用 componentWillMount 中的 AJAX 的原因。但我不确定 100%。
    • 好吧,有趣,我真的无法想象这是怎么发生的,但也许我什么都没有。
    【解决方案3】:

    您不应在 render() 方法中调度操作。以下是来自 react 文档的引用:

    render() 函数应该是纯函数,也就是说它不修改组件状态,每次调用都返回相同的结果,不直接与浏览器交互。如果您需要与浏览器交互,请在 componentDidMount() 或其他生命周期方法中执行您的工作。保持render() pure 使组件更易于思考。

    当您需要从服务器获取数据时,最好在组件挂载后进行,即在componentDidMount() 方法中。反应文档指出:

    componentDidMount() 在组件安装后立即调用。需要 DOM 节点的初始化应该放在这里。如果您需要从远程端点加载数据,这是一个实例化网络请求的好地方。在此方法中设置状态将触发重新渲染。

    如果来自服务器的数据依赖于组件的某些propsstate,您还需要实现componentWillReceiveProps()componentWillUpdate() 函数来获取新数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-24
      • 2018-01-27
      • 2018-12-21
      • 2012-10-03
      • 1970-01-01
      相关资源
      最近更新 更多