首页 文章 使用useReducer整合逻辑

使用useReducer整合逻辑

2024-07-05 23:15  浏览数:251  来源:许某    

到目前为止,我们已经使用了各种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();
}
};



声明:以上文章均为用户自行添加,仅供打字交流使用,不代表本站观点,本站不承担任何法律责任,特此声明!如果有侵犯到您的权利,请及时联系我们删除。

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