Redux 存储不会同步更新?

时间:2021-03-10 21:05:19

标签: reactjs redux

我注意到我的代码中有一些东西,我只是想在这里确认一下。 (使用 Redux 和 React)

假设我有一个按钮,当你点击它时,这个函数被调用:

onClick={ () => {
updateSomeVar(10);
console.log(someVar);
}}

其中 updateValue() 分派了一个将存储中 someVar 的值更新为 10 的操作。 但是,在下面的 console.log 中,它仍然打印旧值 someVar,而不是 10

是不是因为 console.log 在 store 更新触发 React 组件重新渲染之前运行,这就是为什么我们仍然看到旧值? (组件重新渲染后,值确实是10)。

我只是认为 Redux 操作是同步的,所以我希望 console.log 具有最新的值?

1 个答案:

答案 0 :(得分:1)

是的,除非您使用像 synchronous 这样的中间件,否则默认情况下状态更新为 thunk

这里发生的事情是,您在调用重新渲染组件的 updateSomeVar 之后记录值。

每个渲染都有自己的一组值。通过对 setTimeout 使用 console.log 来观察此行为。它仍然会打印旧值。

这是因为组件根据当前闭包使用状态值,因此,当闭包更新时(组件重新渲染时会发生这种情况),状态值将被反映。

这样看,这里是一个非常简单的 React 钩子和状态更新的实现。

  let React = (function() {
  let global = {}; // define a global variable where we store information about the component
  let index = 0; // index to keep track of the component's state
  function render(Component) {
    global.Component = Component;
    const instance = Component(); // get the instance of the component
    index = 0;
    instance.render();  // call the component's render function
    
    global.instance = instance; // store the component's instance for any future calls of the component's functions
    return global; // return the global variable
  }

 function useState(initialState) {
    if (!global) {
      throw new Error("Need a global");
    }

    if (!global.hooks) {
      global.hooks = []; // this array holds the state of the component
    }

    const hooks = global.hooks;
    const currentState = global.hooks[index] || initialState; 
    hooks[index] = currentState;    // memoize the state for future access
   
    const setState = (function() {
      let currentIndex = index; // copy the index so each useState call will have it's own "closed" value over index (currentIndex)
      return function(value) {
        global.hooks[currentIndex] = value;
        render(global.Component);   //re-render the component after state change
      };
    })();
    index = index + 1;
    return [currentState, setState];
  }

  return { render, useState, useEffect };

})();

function Component() {

  // Component is called at each re-render. index is reset to 0.
  
  const [count, setCount] = React.useState(0);
  // hooks: [0], currentIndex: 0,  Incremented Index: 1
  
  const [word, setWord] = React.useState("");
  // hooks: [0, ''], currentIndex: 1,  Incremented Index: 2
  
  const countSetter = () => {
    setCount(count + 1);
  };

  const wordSetter = word => {
    setWord(word);
  };

  function render() {
    console.log(`Count is: ${count}, Word is: ${word}`);
  }
  
  return { render, countSetter, wordSetter };
}

const global = React.render(Component);     // hooks: [ 0, '', [ 0, '' ], [] ]
global.instance.countSetter();              // hooks: [ 1, '', [ 1, '' ], [] ]
global.instance.countSetter();              // hooks: hooks: [ 2, '', [ 2, '' ], [] ]
global.instance.countSetter();              // hooks: [ 3, '', [ 3, '' ], [] ]
global.instance.wordSetter("yooo");         // hooks: [ 3, 'yooo', [ 3, 'yooo' ], [] ]
global.instance.wordSetter("ssup");         // hooks: [ 3, 'yooo', [ 3, 'yooo' ], [] ] 

您的 console.log 关闭了当前渲染的状态变量的值,因此,它返回该特定渲染拥有的值。

通过回顾上面的实现,当组件重新渲染时,索引会被更新,只有这样,新的值才会对组件可用。

这是解释概念的实现链接:

https://rohitpotato.hashnode.dev/how-react-implements-usestate-and-useeffect-internally-a-simplified-overview-1

Github 链接:https://github.com/rohitpotato/implement-react-hooks