Как создать пользовательскую библиотеку управления состоянием с помощью React Hooks и Context API
22 ноября 2022 г.В этой статье я представлю React Context API для управления состоянием и создам решение, аналогичное Redux, без использования сторонней библиотеки.
API контекста React
На самом деле это не новая идея. Context API уже давно является частью React, но только в экспериментальном состоянии.
Начиная с React 16.3.0, он официально стабилен и готов к использованию в рабочей среде.
Без лишних слов, вот шаги
Шаг 1. Создание провайдера и функции подключения (так же, как react-redux connect и Provider) с использованием useReducer, createContext & использоватьконтекст.
import React, { useReducer, createContext, useContext } from "react";
const initialState = {};
// Create App Context
export const Context = createContext(initialState);
export const Provider = ({ children, reducers}) => {
const defaultState = reducers(undefined, initialState);
if (defaultState === undefined) {
throw new Error("reducer's should not return undefined");
}
const [state, dispatch] = useReducer((_state, _action) => {
return reducers(_state, _action);
}, defaultState);
return (
<Context.Provider value={{ state, dispatch }}>
{children}
</Context.Provider>
);
};
export const useDispatch = () => useContext(Context).dispatch;
export const useSelector = (callback) => {
const state = { ...useContext(Context).state };
return callback ? callback(state) : state;
};
Шаг 2. Подключите приложение реагирования к созданному выше провайдеру.
const actionMap = {
INCREMENT: (state, action) => ({ ...state, count: state.count + 1 }),
DECREMENT: (state, action) => ({ ...state, count: state.count - 1 }),
};
const countReducer = (state = { count: 0 }, action) => {
const exec = actionMap[action.type];
return exec ? exec(state, action) : state;
};
const reducers = { countReducer };
const App = () => (
<Provider reducers={reducers}>
<Component />
</Provider>
);
Шаг 3. Подключите компонент к контексту.
const Component = () => {
const dispatch = useDispatch();
const { count } = useSelector((state) => state.countReducer);
return (<h3>Context State: {count} </h3>)
}
Текущая демонстрация: здесь
Бонусный совет
export const combineReducers = (reducers) => {
const entries = Object.entries(reducers);
return (state = {}, action) => {
return entries.reduce((_state, [key, reducer]) => {
_state[key] = reducer(state[key], action);
return _state;
}, {});
};
};
Спасибо, что читаете 😊
Есть дополнительные вопросы? пожалуйста, оставьте комментарий.
Обязательно прочитайте, если еще не читали
Создание пользовательского хука для получения асинхронных данных: useAsync Hook с кэшем
Методы промисов Javascript с примером полифилла: Памятка для Разработчик
==Больше контента на==
Подпишитесь на меня: Github, Twitter , LinkedIn, Medium a>, Dev.to, Blogspot, Hashnode, Stackblitz
Также опубликовано здесь
Оригинал