Fill context from REST API and use it in a React component with useEffect and useContext

Viewed 1169

Prerequisite

I have a form in a component with some inputs and these inputs need some configuration data. The configuration data come from REST API.

Goal

Call the REST API and store the configuration data in React context so it will be reused.

What is done

1/ I created component and its inputs. 2/ I used mock configuration data to render component. 3/ I created the context so I replaced mock configuration data with a new set of configuration data provided by the React context (always mock). 4/ I Filled the context with configuration data from a REST API.

Problem

I use context API in my component but the returned configuration data from context is empty.

interface ContextType {
  formConfig: any[];
}

export const Context = React.createContext<ContextType>({
 formConfig: [],
 getFormConfig: () => [],
});


export const ContextProvider: React.FC<{
  children: React.ReactNode;
}> = ({ children }) => {

  let formConfig: any[] = [];

  function getFormConfig() {
    return formConfig;
  }

  useEffect(() => {
    (async function fetchData() {
      formConfig = await ServiceConfig.getFormTypes();
      console.log(formConfig, 'use effect of context'); // It shows the conf
    })();
  }, []);


  return (
    <Context.Provider
      value={{
        getFormConfig,
        formConfig
      }}
    >
      {children}
    </Context.Provider>
  );
};

const FormUI: React.FC = () => {


    const { getFormConfig } = useContext(Context);

    useEffect(() => {
        console.log(getFormConfig(), 'form'); // it is empty here
    }, []);

    return (
        <ContextProvider>
            ....
        </ContextProvider>
    )
};
1 Answers

let formConfig: any[] = []; is just an variable, when you rerender it, it will be created again and assign [] to it.

You need to store it in a state.

const [formConfig, setFormConfig] = React.useState([])

And in the async function, you set the state

  useEffect(() => {
    (async function fetchData() {
      formConfig = await ServiceConfig.getFormTypes();
      setFormConfig(formConfig) // setting the state
      console.log(formConfig, 'use effect of context'); // It shows the conf
    })();
  }, []);

Sorry for not being able to give you the answer in typescript

Related