为什么在 createContext() 中添加空花括号来帮助处理 API 数据

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

假设我的上下文组件中有以下内容:

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

然后我在另一个组件中调用 useContext(appContext) 以检索携带来自此提供程序的数据的道具。

这个道具持有 API 数据,这是一个对象数组。在某些情况下,我只想通过写 prop[0] 从这个数组的第一个对象中获取数据。现在也许我想通过写 prop[0].objProp

从这个对象的某个 属性 中获取值

我的问题:为什么这只在示例开头的 createContext() 调用中有空花括号时有效?因为没有它,我会收到错误消息“属性 'objProp' of undefined”。

说明

您没有显示所有相关代码来确定到底出了什么问题,但我的猜测是您在渲染 AppContext.Provider.[=26 时没有为 value 属性提供值=]

根据文档 (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.

因此,如果未找到匹配的提供程序,则使用 createContext 的默认值。如果你不传递任何东西,这将是 undefined,如果你传递 {},它将是一个对象。

假设您有以下代码:

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

createContext 未传递默认参数时,前面的代码将出错,因为您尝试访问 undefined 上的 属性。如果设置了默认值,c.value 的值将只是 undefined,因为空对象上没有名为 something 的 属性。


工作示例

现在我真正认为你应该做的是在 AppContext.Provider 上提供 value 道具并做这样的事情:

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;