React系列-Mixin、HOC、Render Props(上)
React系列-轻松学会Hooks(中)
React系列-自定义Hooks很简单(下)
我们在第二篇文章中介绍了一些常用的hooks,接着我们继续来介绍剩下的hooks吧
useReducer
作为useState 的替代方案。它接收一个形如
(state, action) => newState 的 reducer
,并返回当前的 state 以及与其配套的 dispatch 方法
。(如果你熟悉 Redux 的话,就已经知道它如何工作了。)
不明白Redux工作流的同学可以看看这篇Redux系列之分析中间件原理(附经验分享)
为什么使用
官方说法: 在某些场景下,useReducer 会比 useState 更适用,
例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等
。并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化
,因为你可以向子组件传递 dispatch 而不是回调函数 。
总结来说:
如果你的state是一个数组或者对象等复杂数据结构
如果你的state变化很复杂,
经常一个操作需要修改很多state
如果你希望构建自动化测试用例来保证程序的稳定性
如果你需要在深层子组件里面去修改一些状态(也就是useReducer+useContext代替Redux)
如果你用应用程序比较大,希望UI和业务能够分开维护
登录场景
举个例子????:
登录场景
useState完成登录场景
function LoginPage() {
const [name, setName] = useState(''); // 用户名
const [pwd, setPwd] = useState(''); // 密码
const [isLoading, setIsLoading] = useState(false); // 是否展示loading,发送请求中
const [error, setError] = useState(''); // 错误信息
const [isLoggedIn, setIsLoggedIn] = useState(false); // 是否登录
const login = (event) => {
event.preventDefault();
setError('');
setIsLoading(true);
login({ name, pwd })
.then(() => {
setIsLoggedIn(true);
setIsLoading(false);
})
.catch((error) => {
// 登录失败: 显示错误信息、清空输入框用户名、密码、清除loading标识
setError(error.message);
setName('');
setPwd('');
setIsLoading(false);
});
}
return (
// 返回页面JSX Element
)
}
useReducer完成登录场景
const initState = {
name: '',
pwd: '',
isLoading: false,
error: '',
isLoggedIn: false,
}
function loginReducer(state, action) {
switch(action.type) {
case 'login':
return {
...state,
isLoading: true,
error: '',
}
case 'success':
return {
...state,
isLoggedIn: true,
isLoading: false,
}
case 'error':
return {
...state,
error: action.payload.error,
name: '',
pwd: '',
isLoading: false,
}
default:
return state;
}
}
function Log