Home Article Practice 使用useReducer整合逻辑

使用useReducer整合逻辑

2024-07-05 23:15  views:268  source:许某    

到目前为止,我们已经使用了各种state hooks来管理数据,
包括loading、error、data等状态。
但是我们可以看到,这三个有关联的状态确是分散的,它们通过分离的useState来创建,
为了有关联的状态整合到一起,我们需要用到useReducer。
如果你写过redux,那么将会对useReducer非常的熟悉,
可以把它理解为一个轻量额redux。
useReducer 返回一个状态对象和一个可以改变状态对象的dispatch函数。
跟redux类似的,dispatch函数接受action作为参数,
action包含type和payload属性。
我们看一个简单的例子吧:
import React, {
Fragment,
useState,
useEffect,
useReducer,
} from 'react';
import axios from 'axios';
const dataFetchReducer = (state, action) => {
...
};
const useDataApi = (initialUrl, initialData) => {
const [url, setUrl] = useState(initialUrl);
const [state, dispatch] =
useReducer(dataFetchReducer, {
isLoading: false,
isError: false,
data: initialData,
});
...
};
useReducer将reducer函数和初始状态对象作为参数。
在我们的例子中,data,loading和error状态的初始值与useState创建时一致,
但它们已经整合到一个由useReducer创建对象,而不是多个useState创建的状态。
const dataFetchReducer = (state, action) => {
...
};
const useDataApi = (initialUrl, initialData) => {
const [url, setUrl] = useState(initialUrl);
const [state, dispatch] =
useReducer(dataFetchReducer, {
isLoading: false,
isError: false,
data: initialData,
});
useEffect(() => {
const fetchData = async () => {
dispatch({ type: 'FETCH_INIT' });
try {
const result = await axios(url);
dispatch({ type: 'FETCH_SUCCESS',
payload: result.data });
} catch (error) {
dispatch({ type: 'FETCH_FAILURE' });
}
};
fetchData();
}, [url]);
...
};
在获取数据时,可以调用dispatch函数,将信息发送给reducer。使
用dispatch函数发送的参数为object,具有type属性和可选payload的属性。
type属性告诉reducer需要应用哪个状态转换,并且reducer可以使用payload来创建新的状态。
在这里,我们只有三个状态转换:发起请求,请求成功,请求失败。
在自定义hooks的末尾,state像以前一样返回,但是因为我们拿到的是一个状态对象,
而不是以前那种分离的状态,所以需要将状态对象解构之后再返回。
这样,调用useDataApi自定义hooks的人仍然可以访问data,
isLoading 和 isError这三个状态。
const useDataApi = (initialUrl, initialData) => {
const [url, setUrl] = useState(initialUrl);
const [state, dispatch] =
useReducer(dataFetchReducer, {
isLoading: false,
isError: false,
data: initialData,
});
...
const doFetch = url => {
setUrl(url);
};
return { ...state, doFetch };
};
接下来添加reducer函数的实现。
它需要三种不同的状态转换FETCH_INIT,FETCH_SUCCESS和FETCH_FAILURE。
每个状态转换都需要返回一个新的状态对象。让我们看看如何使用switch case语句实现它:
switch (action.type) {
case 'FETCH_INIT':
return {
...state,
isLoading: true,
isError: false
};
case 'FETCH_SUCCESS':
return {
...state,
isLoading: false,
isError: false,
data: action.payload,
};
case 'FETCH_FAILURE':
return {
...state,
isLoading: false,
isError: true,
};
default:
throw new Error();
}
};



Disclaimer: The above articles are added by users themselves and are only for typing and communication purposes. They do not represent the views of this website, and this website does not assume any legal responsibility. This statement is hereby made! If there is any infringement of your rights, please contact us promptly to delete it.

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)