Я создал проект, используя CRA 2.0 с TypeScript.Я пытаюсь использовать Context.
Моя конечная цель - создать универсальное хранилище данных, в котором у меня есть несколько доступных предметов.Я использую машинопись.
См. Приведенный ниже код. У меня вопрос: у меня есть состояние в родительском элементе, я устанавливаю его в состояние и передаю его вниз.Когда я устанавливаю состояние в родительском (у которого есть поставщик контекста), он не перерисовывает дочерний компонент, поэтому даже после извлечения новых данных значение контекста остается внутри дочернего, если я не перерисовываю дочерний компонент.
Interface File (`interfaces/lookups.tsx`)
interface LookupItemInterface {
value?: number;
text?: string;
}
export interface LookupInterface {
assessmentTypesLookUp: LookupItemInterface[];
billingPlansLookUp: LookupItemInterface[];
categoriesLookUp: LookupItemInterface[];
competenciesLookUp: LookupItemInterface[];
emailTypesLookUp: LookupItemInterface[];
entitiesLookUp: LookupItemInterface[];
evaluationRolesLookUp: LookupItemInterface[];
questionTypesLookUp: LookupItemInterface[];
recommendedApplicationsLookUp: LookupItemInterface[];
statesLookUp: LookupItemInterface[];
testTypesLookUp: LookupItemInterface[];
userRolesLookUp: LookupItemInterface[];
}
export const lookupInitialState: LookupInterface = {
assessmentTypesLookUp: [],
billingPlansLookUp: [],
categoriesLookUp: [],
competenciesLookUp: [],
emailTypesLookUp: [],
entitiesLookUp: [],
evaluationRolesLookUp: [],
questionTypesLookUp: [],
recommendedApplicationsLookUp: [],
statesLookUp: [],
testTypesLookUp: [],
userRolesLookUp: [],
};
export interface LookupContextInterface {
findByValue?: (id: number, key: string) => void;
lookups?: LookupInterface;
}
export const LookupContextInitialState = {
findByValue: (id: number, key: string) => {},
lookups: lookupInitialState,
};
Это мой контекстный файл ( LookupContext.tsx )
import { LookupContextInitialState, LookupContextInterface } from '../interfaces/Lookup';
export const LookupContext = React.createContext<LookupContextInterface>(LookupContextInitialState);
export const LookupContextProvider = LookupContext.Provider;
export const LookupContextConsumer = LookupContext.Consumer;
export default LookupContext;
Я создал контейнер, в который упаковываю свой шаблон.
const LookupContainer: React.FunctionComponent = ({ children }) => {
const [lookupState, setLookupState] = useState({ lookups: lookupInitialState, loading: true });
const errorContext = useContext(ErrorContext);
useEffect(() => {
fetchLookups();
}, []);
const findByValue = (id: number, key: string) => {
console.log('find', id, key, lookupInitialState);
};
const fetchLookups = async () => {
try {
const newLookups = await getLookups();
setLookupState({ ...lookupState, lookups: newLookups, loading: false });
} catch (e) {
setLookupState({ ...lookupState, loading: false });
errorContext.setError(e, true);
}
};
if (lookupState.loading) {
return <Spinner />;
}
return <LookupContextProvider value={{ findByValue, lookups: lookupState.lookups }}>{children}</LookupContextProvider>;
};
Я использую Atomic Design Modal, и сейчас я обертываю его в свой шаблон.
const DashboardTemplate: React.FunctionComponent<Props> = ({ children }) => (
<LookupContainer>
<Sidebar />
<Page>
<TopBar />
{children}
<Footer />
</Page>
</LookupContainer>
);
и, наконец, у детей есть контейнер внизу,
const TemplateContainer: React.FunctionComponent = ({ id }) => {
const lookupContext = useContext(LookupContext);
const {lookups, findById} = lookupContext; // <--- this will have initial context value unless I set state inside this and somehow re-render this
const assessmentTypesLookUp = findById(id, 'assessmentTypesLookUp');
return (
<DashboardTemplate>This is Instrument</DashboardTemplate>
);
}