09 useReducer高级用法
所谓高级用法,只不过是一些深 层知识点和实用技巧,你甚至可以把本章当做对前面知识点的一个巩固和学习。
使用useReducer来管理复杂类型的数据
举例,若某组件内通过ajax请求数据,获取最新一条站内短信文字,需要组件显示整个ajax过程及结果:
1、当ajax开始请求时,界面显示“loading...”;
2、当ajax请求发生错误时,界面显示“wrong!”;
3、当ajax请求成功获取数据时,界面显示获取到的数据内容;
如果我们使用useState来实现上述功能,伪代码如下:
function Component() {
const [loading,setLoading] = useState(true); //是否ajax请求中,默认为true
const [result,setResult] = useState(''); //请求数据内容,默认为''
const [error,setError] = useState(false); //请求是否发生错误,默认为false
{
//ajax请求成功
setLoading(false);
setResult('You have a good news!');//请注意,这是一行伪代码,只是为了演示,并不是真正ajax获取的结果
setError(false);
//ajax请求错误
setLoading(false);
setError(true);
}
return <div>
{loading ? 'loading...' : result}
{error ? 'wrong!' : null}
</div>
}
如果我们使用useReducer来实现,则可将上述3个变量都放在我们定义的变量state中,伪代码如下:
const initralData = {loading: true,result: '',error: false};
const reducer = (state, action) => {
switch (action.type) {
case 'succes':
return {loading:false,result:action.res,error:false}
case 'error':
return {loading:false,error:true}
}
}
function Component() {
const [state, dispatch] = useReducer(reducer, initralData);
{
//ajax请求成功
dispatch({type:'succes',res:'You have a good news!'});
//ajax请求错误
dispatch({type:'error'});
}
return <div>
{state.loading ? 'loading...' : state.result}
{state.error ? 'wrong!' : null}
</div>
}
你可能会有疑问?
1、为什么看上去使用useReducer后代码变得更多?
答:因为使用useReducer,我们将修改数据拆分为2个部分,即“抛出修改事件和事件修改处理函数”。虽然代码增多了,但是逻辑更加清晰。
2、为什么不使用useState,同时把它对应的变量也做成一个obj,就像useReducer的initralData那种?
答:单纯从1次ajax请求很难看出使用useState或useReducer的差异,但是试想一下多次且ajax返回值在结构类型上容易发生变更,那么使用useReducer这种更加利于代码阅读、功能扩展。