Я работаю над некоторым внешним кодом, и мы используем React useContext () вместо Redux. Раньше у нас все было в одном контексте, пока я не понял, что каждый элемент, подписанный на useContext, рендерит каждый раз, когда изменяется любое значение в контексте (в отличие от Redux, где вы можете просто подписаться на отдельные изменения в хранилище Redux с помощью используя mapStateToProps.)
Итак, чтобы решить эту проблему, я разбил монолитный c StateManager на несколько контекстов, но теперь мне сложно понять, как выполнить модульное тестирование контекстов.
У меня довольно сложный вопрос, который срабатывает на основе window.addEventListeners - но это тема для другого поста.
Как бы я протестировал этот код?
import React, { createContext, useReducer } from 'react';
import pick from 'lodash/pick';
import isEqual from 'lodash/isEqual';
export interface SocialManagerState {
/* interface def goes here - not important */
}
export const SocialManagerContext = createContext<SocialManagerState>({});
export const SocialManagerDispatchContext = createContext<any>({});
// basically just a shallow merge.
const socialReducer = (
state: SocialManagerState,
action: Partial<SocialManagerState>
): SocialManagerState => {
if (isEqual(pick(state, Object.keys(action)), action)) {
return state;
}
return { ...state, ...action };
};
interface SocialManagerProviderProps {
children: any;
testOverride?: any; // this is only used in unit tests;
[key: string]: any;
}
export const SocialManagerProvider: React.FC<SocialManagerProviderProps> = ({
children,
testOverride
}) => {
const [socialValue, dispatchSocial] = useReducer(socialReducer, {});
if (testOverride) {
console.warn('Social Manager Provider values are being overwritten for test');
dispatchSocial(testOverride);
}
return (
<SocialManagerContext.Provider value={socialValue}>
<SocialManagerDispatchContext.Provider value={dispatchSocial}>
{children}
</SocialManagerDispatchContext.Provider>
</SocialManagerContext.Provider>
);
};
export default SocialManagerContext;