在redux中调度动作后,如何使用useSelector访问state的最新值?

时间:2020-02-21 15:02:55

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

我在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)
};

1 个答案:

答案 0 :(得分:0)

看起来您的getPrivateKey函数是一个笨拙的东西,但是您不是调度吗?并没有阻止您从笨蛋返回值的事情。

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,使其使用传递的值或从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的重击设置某种条件,以便在键为null时不会运行。