Использовать контекст, а не перерисовывать дочернее приложение - PullRequest
0 голосов
/ 10 апреля 2019

Я создал проект, используя 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>
  );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...