【问题标题】:How do I access the latest value of state using useSelector after dispatching an action in redux?在 redux 中调度操作后,如何使用 useSelector 访问状态的最新值?
【发布时间】:2023-03-27 21:39:01
【问题描述】:

我在 React-Native 项目中有一个屏幕,它本质上只是在从服务器获取数据时呈现加载图标,然后将用户带到主屏幕。第一个函数getPrivateKey() 将返回私钥并使用redux 将其存储在状态中,然后下一个函数connectWithKey() 将使用该密钥进行连接。

我面临的问题是,当connectWithkey() 运行时,它使用的是私钥的初始空值,而不是更新后的值。这是代码,如果我很愚蠢,很抱歉,这是漫长的一天:(

export default DataLoader = props => {
  //private key - this should, in theory, update after getPrivateKey()
  const privateKey = useSelector(({ main }) => main.privateKey);
  const dispatch = useDispatch();

  useEffect(() => {
    const configure = async () => {
      //this will update the private key
      await getPrivateKey();

      //this should use the new private key from useSelector, but instead is using the initialised empty object
      await connectWithKey();

      props.navigation.navigate('MainScreen');
    };
    configure();
  }, []);

//.... more code below....

我尝试将 privateKey 添加到刚刚导致无限循环的数组依赖项中,并且我检查了 redux 存储中的值是否已更新 - 所以我有点迷路了!从本质上讲,useSelector 钩子似乎没有获得新的价值。任何帮助将不胜感激???谢谢!

编辑 - 应要求添加更多代码 ????

const getPrivateKey = async () => {
  const privKey = await fetchKeyFromServer();
  dispatch({
   type: 'UPDATE',
   value: privKey 
  });
};

const connectWithkey = async () => {
  //the privateKey here should be the updated value from useSelector
  await connectToServer(privateKey)
};

【问题讨论】:

  • 它会导致无限循环,因为您正在更新和使用同一组件中的变量。您更新变量(通过调度或其他方式),这会导致从商店中选择它的所有事物重新渲染,您的组件就是其中之一,因此您的组件重新渲染并在此过程中更新变量....
  • 嗨亚当 - 感谢您的回复!这完全有道理,我现在看到更新它会导致重新渲染,因此组件重新渲染,更新变量和繁荣重复......我只是发现当我在变量中包含 privateKey 时存在无限循环,而不是我在上面列出的 - 它只是指来自 useSelector 的旧值 - 你知道我将如何使用最近的值吗?
  • 看来函数 A 需要运行才能将某些东西放入 redux 存储中,但随后函数 B 需要存储中的值,并且它使用的是 A 更改之前的值。
  • 这很简单 - 在单独的组件中完成工作。
  • 这样想——你已经将 privateKey 的使用和它的更新紧密地联系在一起——每当 privateKey 更新时,你就请求一个新的 privateKey。这不是您想要发生的逻辑。确切地说,您想在什么时候更新 privateKey?

标签: javascript reactjs react-native redux react-redux


【解决方案1】:

看起来你的getPrivateKey 函数是一个thunk,但你没有调度它?并且没有什么可以阻止您从 thunk 返回值。

const getPrivateKey = async (dispatch) => {
  const privKey = await fetchKeyFromServer();
  dispatch({
   type: 'UPDATE',
   value: privKey 
  });
  return privKey // return the key here to whoever wants to use the value immediately.
};

然后在组件中的useEffect 中,您可以轻松使用返回值:)

useEffect(() => {
    const configure = async () => {
      //make sure you 'dispatch' this thunk
      const key = await dispatch(getPrivateKey());

      // pass the key
      await dispatch(connectWithKey(key));
      ...
    };
    ....
  }, []);

上面的代码假设connectWithKey 也是一个thunk。如果是这样,您可以将 thunk 设计为使用传递的值或从 redux 存储中读取它。

const connectWithkey = (privateKey: passedPrivateKey) = async (dispatch, getState) => {
  const state = getState();
  let privateKey = state.whatever.the.path.is.to.privateKey;

  // use the passed private key if it is present.
  if (passedPrivateKey) {
    privateKey = passedPrivateKey;
  }

  await connectToServer(privateKey)
};

我在我的应用程序中多次使用过这种方法。这样您就不需要依赖选择器中的状态。如果您选择依赖该状态,您的 useEffect 的依赖关系应该相应更新。现在它是一个空数组,这就是效果不会在任何状态更改时再次运行的原因(它的作用类似于 componentDidMount 生命周期函数)。

const privateKey = useSelector(({ main }) => main.privateKey);

useEffect(() => {
 await getPrivateKey();

 if (privateKey) {
   await connectWithKey();
 }
}, [privateKey]);

这样,每次privateKey 状态更改时,您的钩子都会重新运行。不过,您可能需要为您的 connectWithKey thunk 设置某种条件,以便在密钥为空时它不会运行。

【讨论】:

    猜你喜欢
    • 2019-12-04
    • 1970-01-01
    • 2021-05-05
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多