如何使用 useEffect 钩子来初始化 reducerstate

时间:2021-06-05 23:07:08

标签: reactjs react-hooks

所以我的问题是我想使用一个函数来生成我的初始状态,然后在我的减速器中使用该生成的状态。

我的 App 组件函数之外有这个 StateGenerator() 函数,它返回一个大数组。

如果我这样写:

const [boardState, tileDispatchFn] = useReducer(
    tileReducer,
    StateGenerator()
  );

它可以工作,但是 StateGenerator() 函数在每次渲染时都会执行(这正常吗??)尽管状态没有重置为初始状态(我猜这很好??)

但是这些函数仍然会在每次渲染时执行,并且会生成一个相当大的数组,如果我通过单击它来快速渲染,则会中断

如果我这样写:

let initState = null;

useEffect(() => {
    initState = StateGenerator();
  }, []);

  const [boardState, tileDispatchFn] = useReducer(
    tileReducer,
    initState
  );

我收到这样的错误 Cannot read property ... of null 因为 useEffect 在渲染之后执行

使用 StateGenerator() 函数生成初始状态的最简单方法是什么?这样做的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

我认为最简单的方法是使用 useReducer 的第三个参数,这是一个初始化函数。

useReducer - const [state, dispatch] = useReducer(reducer, initialArg, init);

Lazy initialization

<块引用>

你也可以懒惰地创建初始状态。为此,您可以通过 init 函数作为第三个参数。初始状态将被设置 到init(initialArg)

它让你提取计算初始状态的逻辑 减速机外。

我不知道你的状态是什么样的,但这是它的用途。

const [boardState, tileDispatchFn] = useReducer(
  tileReducer,
  {              // <-- default initial board state
    // state keys with safe default values
  },
  StateGenerator // <-- state initializer function
);

答案 1 :(得分:0)

您可以调度一个设置减速器初始状态的动作。当组件挂载时,您可以调度操作以从任何组件设置状态,例如:

import React from "react";
const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case "set_initial":
      return { count: action.payload };
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

export default function App() {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  React.useEffect(() => {
    dispatch({ type: "set_initial", payload: 10 });
  }, []);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
    </>
  );
}
相关问题