如何使用 useReducer 而不是 useState?
How to use useReducer instead of useState?
嗨,我的初始状态是空对象,
let [value,setValue] = useState({});
function onSubmit(){
setValue({"new Object"})
}
并在单击按钮时将其更新为提交。有没有什么方法可以在 useReducer 中实现这个场景,而且我想在这里创建一个新状态而不是改变它。非常感谢您的帮助或建议。
useReducer
使用的reducer
是一个以当前状态调用的函数,也是一个改变状态的动作。动作可以是任何你想要的。
您可以通过从 reducer 返回新的状态(动作),用 useReducer
轻松创建 useState
:
const { useReducer } = React;
function reducer(_, newState) {
return newState;
}
function App() {
const [value, setValue] = useReducer(reducer, { a: "2" });
function onSubmit() {
setValue({ b: 2 });
}
return (
<div className="App">
<button onClick={onSubmit}>onSubmit</button>
{JSON.stringify(value)}
</div>
);
}
ReactDOM.render(
<App />,
root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<Div id="root"></div>
但是,如果你只是需要替换当前状态,useState
就足够了。但是,如果您想通过替换它来添加到当前状态,useReducer
是一个不错的选择:
const { useReducer } = React;
function reducer(state, newState) {
return {
...state,
...newState
};
}
function App() {
const [value, setValue] = useReducer(reducer, { a: "1" });
function onSubmit() {
setValue({ b: 2 });
}
return (
<div className="App">
<button onClick={onSubmit}>onSubmit</button>
{JSON.stringify(value)}
</div>
);
}
ReactDOM.render(
<App />,
root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<Div id="root"></div>
经过reducer后的状态为{ a: 1, b: 2 }
.
经典的方法是传递一个带有类型和负载的动作。根据类型 reducer 然后可以 "decide" 对 payload 做什么,以及当前状态来生成新的状态。参见 useReducer
api documentation。
两个钩子都定义了一个初始状态和return一个setter和一个getter来处理状态:
[value,fn] = useReducer(...); // or useState(...);
但是,在上面的代码片段中,fn
的行为不同于 useReducer
到 useState
。此外,useReducer
需要 2 个参数,而 useState
只需要 1 个。基本上:
useReducer
:需要 2 个参数,(a) 一个函数(称为 reducer 函数),以及 (b) 状态的初始值。每当您使用某个值调用 fn
时,都会调用 reducer 函数来修改状态。传递给 fn
的值将传递给 reducer 函数(作为第二个参数)。
useState
:只需要 1 个参数,即状态的初始值。它只会用作为参数传递给 fn
的值替换状态(可选地,您也可以将函数传递给 fn
,该函数接收当前状态作为参数和 return这是新状态)。
useState
示例:
const { useState } = React;
const App = () => {
const initialState = { called: false, name: 'Jane' };
const [value, setValue] = useState(initialState);
const replaceState = () => {
setValue({
called: true,
fullName: `${value.name ? value.name : 'Just'} Fonda`
});
}
return (
<div className="App">
<button onClick={replaceState}>Replace Name</button>
<button onClick={(e) => setValue(initialState)}>Reset</button>
<pre>{JSON.stringify(value)}</pre>
{value.called
? <pre>Notice that there's no 'name' attribute anymore</pre>
: null}
</div>
);
}
ReactDOM.render(<App />,root);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
useReducer
的例子:
您必须构建一个函数(reducer
)来修改状态。该函数必须接收 2 个参数:实际状态和您需要修改状态的任何值。
此外,此函数必须return一个值,React 将其设置为新状态。
如果你曾经使用过 redux 模式,你一定很熟悉这种行为。所以,如果你和大家一样,想坚持 redux 模式,使用 action
作为 reducer 函数的第二个参数的名称(将用于修改州)。它将是一个包含 2 个属性的对象:type
和 payload
.
reducer 内部的逻辑处理动作,通过使用 type
(字符串)来决定如何使用 payload
(任意)修改状态。在 reducer 中有一个 switch-case
并不少见。所以,让我们遵循传统,使用这种类似于 redux 的模式构建一个 reducer。
const { useReducer } = React;
// Notice the two parameters of the reducer:
// state: current state
// payload: object with the shape {type: string, payload: any}
// Also, notice that the reducer MUST return a value to be used
// as the new state. Remember that if you return nothing
// javascript will return undefined
const reducer = (state, action) => {
switch(action.type) {
case 'inc': return state + action.payload;
case 'dec': return state - action.payload;
// for any other type, return the current state
default: return state;
}
}
const App = () => {
// specify the reducer and an initial value for the state
const [value, setValue] = useReducer(reducer, 0);
const inc = (e) => setValue({type: 'inc', payload: 1});
const dec = (e) => setValue({type: 'dec', payload: 1});
return (
<div className="App">
<button onClick={inc}>Increment</button>
<button onClick={dec}>Decrement</button>
Counter:{value}
</div>
);
}
ReactDOM.render(<App />,root);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
作为最后的旁注,我在上面的代码片段中使用的 setValue
名称甚至与 useReducer
编辑的函数 return 使用的最常用名称相去甚远.将其称为 dispatch
.
更为常见
嗨,我的初始状态是空对象,
let [value,setValue] = useState({});
function onSubmit(){
setValue({"new Object"})
}
并在单击按钮时将其更新为提交。有没有什么方法可以在 useReducer 中实现这个场景,而且我想在这里创建一个新状态而不是改变它。非常感谢您的帮助或建议。
useReducer
使用的reducer
是一个以当前状态调用的函数,也是一个改变状态的动作。动作可以是任何你想要的。
您可以通过从 reducer 返回新的状态(动作),用 useReducer
轻松创建 useState
:
const { useReducer } = React;
function reducer(_, newState) {
return newState;
}
function App() {
const [value, setValue] = useReducer(reducer, { a: "2" });
function onSubmit() {
setValue({ b: 2 });
}
return (
<div className="App">
<button onClick={onSubmit}>onSubmit</button>
{JSON.stringify(value)}
</div>
);
}
ReactDOM.render(
<App />,
root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<Div id="root"></div>
但是,如果你只是需要替换当前状态,useState
就足够了。但是,如果您想通过替换它来添加到当前状态,useReducer
是一个不错的选择:
const { useReducer } = React;
function reducer(state, newState) {
return {
...state,
...newState
};
}
function App() {
const [value, setValue] = useReducer(reducer, { a: "1" });
function onSubmit() {
setValue({ b: 2 });
}
return (
<div className="App">
<button onClick={onSubmit}>onSubmit</button>
{JSON.stringify(value)}
</div>
);
}
ReactDOM.render(
<App />,
root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<Div id="root"></div>
经过reducer后的状态为{ a: 1, b: 2 }
.
经典的方法是传递一个带有类型和负载的动作。根据类型 reducer 然后可以 "decide" 对 payload 做什么,以及当前状态来生成新的状态。参见 useReducer
api documentation。
两个钩子都定义了一个初始状态和return一个setter和一个getter来处理状态:
[value,fn] = useReducer(...); // or useState(...);
但是,在上面的代码片段中,fn
的行为不同于 useReducer
到 useState
。此外,useReducer
需要 2 个参数,而 useState
只需要 1 个。基本上:
useReducer
:需要 2 个参数,(a) 一个函数(称为 reducer 函数),以及 (b) 状态的初始值。每当您使用某个值调用fn
时,都会调用 reducer 函数来修改状态。传递给fn
的值将传递给 reducer 函数(作为第二个参数)。useState
:只需要 1 个参数,即状态的初始值。它只会用作为参数传递给fn
的值替换状态(可选地,您也可以将函数传递给fn
,该函数接收当前状态作为参数和 return这是新状态)。
useState
示例:
const { useState } = React;
const App = () => {
const initialState = { called: false, name: 'Jane' };
const [value, setValue] = useState(initialState);
const replaceState = () => {
setValue({
called: true,
fullName: `${value.name ? value.name : 'Just'} Fonda`
});
}
return (
<div className="App">
<button onClick={replaceState}>Replace Name</button>
<button onClick={(e) => setValue(initialState)}>Reset</button>
<pre>{JSON.stringify(value)}</pre>
{value.called
? <pre>Notice that there's no 'name' attribute anymore</pre>
: null}
</div>
);
}
ReactDOM.render(<App />,root);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
useReducer
的例子:
您必须构建一个函数(reducer
)来修改状态。该函数必须接收 2 个参数:实际状态和您需要修改状态的任何值。
此外,此函数必须return一个值,React 将其设置为新状态。
如果你曾经使用过 redux 模式,你一定很熟悉这种行为。所以,如果你和大家一样,想坚持 redux 模式,使用 action
作为 reducer 函数的第二个参数的名称(将用于修改州)。它将是一个包含 2 个属性的对象:type
和 payload
.
reducer 内部的逻辑处理动作,通过使用 type
(字符串)来决定如何使用 payload
(任意)修改状态。在 reducer 中有一个 switch-case
并不少见。所以,让我们遵循传统,使用这种类似于 redux 的模式构建一个 reducer。
const { useReducer } = React;
// Notice the two parameters of the reducer:
// state: current state
// payload: object with the shape {type: string, payload: any}
// Also, notice that the reducer MUST return a value to be used
// as the new state. Remember that if you return nothing
// javascript will return undefined
const reducer = (state, action) => {
switch(action.type) {
case 'inc': return state + action.payload;
case 'dec': return state - action.payload;
// for any other type, return the current state
default: return state;
}
}
const App = () => {
// specify the reducer and an initial value for the state
const [value, setValue] = useReducer(reducer, 0);
const inc = (e) => setValue({type: 'inc', payload: 1});
const dec = (e) => setValue({type: 'dec', payload: 1});
return (
<div className="App">
<button onClick={inc}>Increment</button>
<button onClick={dec}>Decrement</button>
Counter:{value}
</div>
);
}
ReactDOM.render(<App />,root);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
作为最后的旁注,我在上面的代码片段中使用的 setValue
名称甚至与 useReducer
编辑的函数 return 使用的最常用名称相去甚远.将其称为 dispatch
.