Managing Complex State with Action Creators
Illustrate the use of action creators within custom hooks for managing complex state logic and asynchronous operations more cleanly.
const useCustomHook = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const fetchData = useCallback(async () => {
dispatch({ type: 'FETCH_REQUEST' });
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
dispatch({ type: 'FETCH_SUCCESS', payload: data });
} catch (error) {
dispatch({ type: 'FETCH_FAILURE', error });
}
}, [dispatch]);
return { state, fetchData };
};
Defines a custom hook using useReducer for state management. Includes a fetchData function to handle asynchronous API calls, dispatching actions for different states of the request (request, success, failure).
const initialState = {
loading: false,
data: null,
error: null
};
Initial state setup for the useReducer hook, establishing the structure for loading, data, and error states.
const reducer = (state, action) => {
switch (action.type) {
case 'FETCH_REQUEST':
return { ...state, loading: true, error: null };
case 'FETCH_SUCCESS':
return { ...state, loading: false, data: action.payload };
case 'FETCH_FAILURE':
return { ...state, loading: false, error: action.error };
default:
return state;
}
};
Reducer function for handling actions dispatched by the custom hook, managing the state based on the action type.
const Component = () => {
const { state, fetchData } = useCustomHook();
useEffect(() => {
fetchData();
}, [fetchData]);
if (state.loading) return <div>Loading...</div>;
if (state.error) return <div>Error: {state.error.message}</div>;
return <div>{JSON.stringify(state.data)}</div>;
};
React component example utilizing the custom hook. It fetches data on mount and renders based on the state (loading, error, data).