在 Redux 中更新状态后如何触发关闭回调?

IT技术 javascript reactjs redux
2021-04-11 04:50:47

在 React 中,状态不会立即更新,因此我们可以在setState(state, callback). 但是如何在 Redux 中做到呢?

调用 之后this.props.dispatch(updateState(key, value)),我需要立即对更新的状态做一些事情。

有什么方法可以像我在 React 中所做的那样使用最新状态调用回调?

6个回答

应该更新组件以接收新的props。

有几种方法可以实现您的目标:

1. componentDidUpdate检查值是否改变,然后做一些事情..

 componentDidUpdate(prevProps){
     if(prevProps.value !== this.props.value){ alert(prevProps.value) }
  }

2. redux-promise(中间件会分发promise的解析值)

export const updateState = (key, value)=>
Promise.resolve({
  type:'UPDATE_STATE',
  key, value
})

然后在组件中

this.props.dispatch(updateState(key, value)).then(()=>{
   alert(this.props.value)
})

2. redux-thunk

export const updateState = (key, value) => dispatch => {
  dispatch({
    type: 'UPDATE_STATE',
    key,
    value,
  });
  return Promise.resolve();
};

然后在组件中

this.props.dispatch(updateState(key, value)).then(()=>{
   alert(this.props.value)
})
在您的redux-thunk示例中,您使用dispatch好像它是同步的。是这样吗?
2021-05-25 04:50:47
@DrazenBjelovuk 我想知道是因为 redux-thunk 示例中的 updateState 函数有 dispatch(someAction) 紧随其后的 return Promise.resolve()。Promise立即解决,我想这会在 redux 存储更新和组件中调用的 .then 之间产生竞争条件。因为 dispatch 不返回 promise 或接受回调,我认为这不是知道 redux store 何时更新的准确方法。我认为在这种情况下 just-boris 的回答是正确的
2021-06-06 04:50:47
我试图在这里使用 redux-thunk 解决方案,但我只得到TypeError: _this.props.dispatch is not a function?
2021-06-11 04:50:47
@DannyHarding 是的,我同意这种方法可能不是一个确定的火灾保证,只是说明调度不是同步的。
2021-06-13 04:50:47
@DannyHardingdispatch不是同步的。如果没有Promise.resolve(),this.props.value仍会返回旧值。仍然需要某种异步延迟(setTimeout例如,从 a 内部引用也可以)。
2021-06-20 04:50:47

使用钩子 API:

useEffect 以props作为输入。

import React, { useEffect} from 'react'
import { useSelector } from 'react-redux'

export default function ValueComponent() {
   const value = useSelector(store => store.pathTo.value)

   useEffect(() => {
     console.log('New value', value) 
     return () => {
        console.log('Prev value', value) 
     }

   }, [value])

   return <div> {value} </div>
}
同意@mkatanski,每次都使用效果触发器,这样处理是不自然的
2021-06-04 04:50:47
接受的答案是在 React Hooks 之前写的。在引入钩子之后,这应该是现在公认的答案。这是一种更被动的方式来处理变化。
2021-06-10 04:50:47
不一定。如果您想在单击按钮时使用更新的商店数据触发一个函数,但又不想在每次特定数据发生更改时触发该函数,该怎么办?
2021-06-13 04:50:47

React 最重要的一点是单向数据流。在您的示例中,这意味着应该将分发操作和状态更改处理分离。

你不应该想像“我做了A,现在X变成了Y我处理它”,而是“当X变成时我该怎么办Y”,与A. Store 状态可以从多个来源更新,除了你的组件,Time Travel 也可以改变状态,它不会通过你的A调度点传递

基本上这意味着您应该componentWillReceiveProps按照@Utro 的建议使用

这是 op 真正要寻找的答案(尽管他似乎不知道这一点..)
2021-06-03 04:50:47
我同意,但这似乎被认为是一种反模式:hackernoon.com/...
2021-06-16 04:50:47
componentWillReceiveProps推荐使用的我们现在该怎么做static getDerivedStateFromProps()据我所知,它似乎不是一个合适的替代品,因为它不能调用回调
2021-06-21 04:50:47

您可以使用subscribe侦听器,它会在分派动作时被调用。在侦听器内,您将获得最新的商店数据。

http://redux.js.org/docs/api/Store.html#subscribelistener

这在使用基于函数的组件时是首选..
2021-05-26 04:50:47
未找到链接页面
2021-05-28 04:50:47
subscribe仅在分派动作时触发。有没有办法subscribe将让你知道,如果你的API调用返回的任何数据。我想!:D
2021-06-02 04:50:47
当您的请求完成(成功或不成功)时,您可以分派另一个动作。
2021-06-15 04:50:47
我不相信这里提出的任何其他解决方案实际上有效,因为我没有看到在状态更新后解决Promise或触发回调的方法。每次商店更新都会调用此方法,而不仅仅是在您的事件之后发生的更新,但这应该不会太难解决。特别是,从您链接到的页面编写自定义observeStore 实用程序的链接非常有帮助。
2021-06-15 04:50:47

您可以使用带有回调的 thunk

myThunk = cb => dispatch =>
  myAsyncOp(...)
    .then(res => dispatch(res))
    .then(() => cb()) // Do whatever you want here.
    .catch(err => handleError(err))
非常适合我所需要的!
2021-05-26 04:50:47