Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
271 views
in Technique[技术] by (71.8m points)

reactjs - Why add empty curly braces in createContext() to help handle API data

Say I have the following in my Context component:

export const AppContext = createContext({});

export const Provider = ({children}) => {

    const [data, setData] = useState([]);

    const getData = async () => {
        try {
            await axios.get(<apiUrl>)
                       .then(data => setData(data.data));      
        } catch (err) {
            console.error(err.message);
        }
    }
    
    useEffect(() => {
        getData();
    }, []);

// etc. code below

I then call useContext(appContext) in another component to retrieve the prop carrying the data from this provider.

This prop holds API data which is an array of objects. In a certain circumstance, I would want to grab only the data from the first object of this array by writing prop[0]. Now maybe I want to grab the value from a certain property of this object by then writing prop[0].objProp

My question: Why does this only work when there are empty curly braces inside the createContext() call at the beginning of the example? Because without that, I would receive the error "Property 'objProp' of undefined".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Explanation

You are not showing all relevant code to determine what exactly is going wrong, but my guess is that you have not provided a value for the value prop when rendering AppContext.Provider.

According to the documentation (https://reactjs.org/docs/context.html#reactcreatecontext):

The defaultValue argument is only used when a component does not have a matching Provider above it in the tree.

So if a matching provider is not found the default value of of createContext is used. If you don't pass anything this will be undefined, if you pass {} it will be an object.

Let's say you have the following code:

const c = React.useContext(AppContext)
console.log(c.value)

When createContext is not passed a default argument the previous code will error, because you try to access a property on undefined. If the default value was set, the value of c.value will just be undefined, because there is no property named something on an empty object.


Working Example

Now what I actually think you should do is to provide the value prop on AppContext.Provider and do something like this:

import React from "react";
import axios from "axios";

const AppContext = React.createContext();

const Provider = ({ children }) => {
  const [data, setData] = React.useState([{title: ''}]); // Need default value with all fields in the object you plan on receiving

  const getData = async () => {
    try {
      await axios
        .get("https://jsonplaceholder.typicode.com/posts")
        .then((data) => {
          setData(data.data);
        });
    } catch (err) {
      console.error(err.message);
    }
  };

  React.useEffect(() => {
    getData();
  }, []);

  return (
    <AppContext.Provider value={{data: data}}>
      {children}
    </AppContext.Provider>
  );
};

const TestComponent = () => {
  const c = React.useContext(AppContext) 
  return c.data[0].title // Do something with the data...
};

const App = () => {
  return (
    <div>
      <Provider>
        <TestComponent />
      </Provider>
    </div>
  );
};

export default App;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...