我使用带有TypeScript的CRA 2.0创建了一个项目。我正在尝试使用上下文。
我的最终目标是创建一个通用数据存储,其中几乎没有可用的项目。我正在使用打字稿。
请参阅下面的代码,我的问题是,我在父级中有一个状态,我将其设置为状态并传递给它。当我在父级(带有上下文提供程序的一个)中设置状态时,它不会重新渲染子级组件,因此,即使在获取新数据后,除非重新渲染子级组件,上下文值在子级内部仍保持不变。
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>;
};
我正在使用原子设计模态,现在将其包装在模板上。
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>
);
}