使用Reducer init 作为道具
useReducer init as props
这里为什么会报错:
Objects are not valid as a React child (found: object with keys
{count}). If you meant to render a collection of children, use an
array instead.
如果你不使用 prop init 就没有错误
import { useReducer } from "react";
function init(initialCount) {
return { count: initialCount };
}
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: +state.count + 1 };
case "decrement":
return { count: +state.count - 1 };
case "reset":
return init(action.payload);
default:
throw new Error();
}
}
function Counter({reducer, initialCount, init}) {
const [state, dispatch] = useReducer(reducer, initialCount, init);
return (
<>
Count: {state.count}
<button
onClick={() =>
dispatch({ type: "reset", payload: initialCount })
}
>
{" "}
Reset
</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
</>
);
}
export default function App() {
return (
<div className="App">
{/* <Counter reducer={reducer} initialCount={{count: 0}} /> */}
<Counter reducer={reducer} initialCount={{count: 0}} init={init} />
</div>
);
}
在这种情况下:
const [state, dispatch] = useReducer(reducer, initialArg, init);
docs 说:
You can also create the initial state lazily. To do this, you can pass
an init function as the third argument. The initial state will be set
to init(initialArg).
在你的情况下 initialArg
与 initialCount
相同,后者是一个对象 ,因此它将调用以下函数,对象作为参数:
function init(initialCount) {
return { count: initialCount };
}
它会 return 对象,其中 count
也指一个对象。 然后你试图渲染一个对象,反应抱怨.
这里为什么会报错:
Objects are not valid as a React child (found: object with keys {count}). If you meant to render a collection of children, use an array instead.
如果你不使用 prop init 就没有错误
import { useReducer } from "react";
function init(initialCount) {
return { count: initialCount };
}
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: +state.count + 1 };
case "decrement":
return { count: +state.count - 1 };
case "reset":
return init(action.payload);
default:
throw new Error();
}
}
function Counter({reducer, initialCount, init}) {
const [state, dispatch] = useReducer(reducer, initialCount, init);
return (
<>
Count: {state.count}
<button
onClick={() =>
dispatch({ type: "reset", payload: initialCount })
}
>
{" "}
Reset
</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
</>
);
}
export default function App() {
return (
<div className="App">
{/* <Counter reducer={reducer} initialCount={{count: 0}} /> */}
<Counter reducer={reducer} initialCount={{count: 0}} init={init} />
</div>
);
}
在这种情况下:
const [state, dispatch] = useReducer(reducer, initialArg, init);
docs 说:
You can also create the initial state lazily. To do this, you can pass an init function as the third argument. The initial state will be set to init(initialArg).
在你的情况下 initialArg
与 initialCount
相同,后者是一个对象 ,因此它将调用以下函数,对象作为参数:
function init(initialCount) {
return { count: initialCount };
}
它会 return 对象,其中 count
也指一个对象。 然后你试图渲染一个对象,反应抱怨.