为什么在 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;
假设我的上下文组件中有以下内容:
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;