有人可以解释一下createStore函数,以及将计数器函数传递给它如何使它知道状态吗?

时间:2019-03-24 09:54:39

标签: javascript reactjs redux

此createStore函数接受reducer函数,但我不太了解发生了什么,当我们执行store.getState()时,它如何知道计数器的当前状态,我知道createStore( )将返回函数的对象,但我不知道它们是如何工作的。 另外,为什么我们需要Listeners数组,我知道有人解释了,但是我正在寻找一个简单的示例,如果有人解释了该数组将具有什么以及为什么我们最后取消订阅这些监听器,我将不胜感激。

如果有人向我解释了如何调试该代码,我真的会很感激,因为我在Chrome调试器中不断得到空值。

最后一个问题,只是传递计数器函数如何使它知道其状态。我在reducer函数本身内部没有看到像state = state这样的赋值。 提前非常感谢您。

const counter = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default: 
      return state;
  }
}

const createStore = (reducer) => {
  let state;
  let listeners = [];

  const getState = () => state;

  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };

  const subscribe = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    };
  };

  dispatch({});

  return { getState, dispatch, subscribe };
};

const store = createStore(counter);

const render = () => {
  document.body.innerText = store.getState();
};

store.subscribe(render);
render();

document.addEventListener('click', () => {
  store.dispatch({ type: 'INCREMENT' });
});

1 个答案:

答案 0 :(得分:4)

  

当我们执行store.getState()时,如何知道计数器的当前状态?

它存储在state变量中。最初是undefined,每当您调用dispatch时,它将调用传递的化径器并派生新状态。要获得初始状态,它可以:

 dispatch({});

然后将减速器称为:

 state = reducer(/*state: */ undefined, /*action: */ {}) /*0*/

将进入开关的默认分支,并返回0,因此state从现在开始为0。如果您再次致电调度,例如:

  dispatch({ type: "INCREMENT" });

然后,reducer再次被调用,但是这一次进入开关的另一个暂存区,状态被增加:

 state = reducer(/*state:*/ 0, /*action:*/ { type: "INCREMENT" }) /*1*/
  

还有,为什么我们需要Listeners数组?

因为每当某些状态发生变化时,页面的多个部分可能都需要更新。因此,您可以将多个侦听器附加到它,然后在状态更新时被调用。

  

为什么我们最后要取消订阅那些听众?

因为在某些情况下,侦听器正在更新的页面部分已消失,然后仍然对其进行更新几乎没有意义,这只会浪费计算时间。通过取消订阅,您可以删除侦听器,因此不再发生更新。

  

仅通过计数器功能如何使它知道其状态?

不是。如上所示,reducer(在这种情况下为counter)通过空操作被调用,这将导致初始状态。

  

如果有人向我解释如何调试该代码,我也将非常感谢

我将放置一些断点,例如在countdispatchrender函数和onClick处理函数的第一行中,然后重新加载页面以查看它从count内调用dispatch,然后每次单击该页面时,它将遍历onClick-> dispatch-> count-> {{1 }}。