useContext returns 值多次,仅调用 1 次
useContext returns values multiple times when called only 1 time
我想从 API 获取数据并将其存储在 context 中,以便在多个组件上使用该数据。此 API 有多个端点,我需要用户 ID 才能访问它们。为此,我从 useParams 获取 id,并使用上下文传递的挂钩 setID 更改 id。
问题是:当我console.log更改ID后的数据时,控制台显示4个不同的数据,在useEffect中一步一步显示:
- 首先是上下文的初始状态(我理解那个)
- 第二个 ID 已更改
- 第三个错误已更改
- 最后一个数据改变了
但是我只是在useEffect回调中设置了id,所以我不明白为什么它会在值更改1次时触发4次。
我不知道我这样做的方式是否正确(如果使用上下文在那里是一件坏事),或者只是我误解了 useEffect 和 useContext。
// Component receiving the data
function APIChecker(){
const {id} = useParams();
const data = useContext(DataContext);
data.setID(id);
console.log(data);
return(
<>
</>
);
}
export default APIChecker;
// Context
export const DataContext = React.createContext();
export const DataProvider = ({children}) => {
const [id, setID] = useState(null);
const initialData = {
globalInfo: [],
activity: [],
averageSession: [],
performance: []
}
const [data, setData] = useState(initialData);
const [error, setError] = useState(404);
useEffect(() => {
const url = "http://localhost:3000/user/";
const fetchData = async () =>{
Promise.all([
fetch(url + id),
fetch(url + id + "/activity"),
fetch(url + id + "/average-sessions"),
fetch(url + id + "/performance")
]).then(([responseGlobal, responseActivity, responseSessions, responsePerformance]) => Promise.all([responseGlobal.json(), responseActivity.json(), responseSessions.json(), responsePerformance.json(), responseGlobal.status
])).then(([responseGlobal, responseActivity, responseSessions, responsePerformance, statusError]) => {
setError(statusError);
setData({
globalInfo: responseGlobal,
activity: responseActivity,
averageSessions: responseSessions,
performance: responsePerformance
});
}).catch(error => {
throw new Error(error);
});
}
if(id != null){
fetchData();
}
}, [id])
return(
<DataContext.Provider value={{id, data, setID, error}}>
{children}
</DataContext.Provider>
)
}
每次您的子组件 APIChecker 调用 setID 时,这将触发父组件中的 useEffect,因为您已在依赖数组中传递了 id。
这反过来会多次调用 API。
useEffect(()=>{
/*your implementation*/
},[id]);
如果你只想调用一次,只需传递空数组作为依赖项,如下所示:
useEffect(()=>{
/*your implementation*/
},[]);
我想从 API 获取数据并将其存储在 context 中,以便在多个组件上使用该数据。此 API 有多个端点,我需要用户 ID 才能访问它们。为此,我从 useParams 获取 id,并使用上下文传递的挂钩 setID 更改 id。
问题是:当我console.log更改ID后的数据时,控制台显示4个不同的数据,在useEffect中一步一步显示:
- 首先是上下文的初始状态(我理解那个)
- 第二个 ID 已更改
- 第三个错误已更改
- 最后一个数据改变了
但是我只是在useEffect回调中设置了id,所以我不明白为什么它会在值更改1次时触发4次。
我不知道我这样做的方式是否正确(如果使用上下文在那里是一件坏事),或者只是我误解了 useEffect 和 useContext。
// Component receiving the data
function APIChecker(){
const {id} = useParams();
const data = useContext(DataContext);
data.setID(id);
console.log(data);
return(
<>
</>
);
}
export default APIChecker;
// Context
export const DataContext = React.createContext();
export const DataProvider = ({children}) => {
const [id, setID] = useState(null);
const initialData = {
globalInfo: [],
activity: [],
averageSession: [],
performance: []
}
const [data, setData] = useState(initialData);
const [error, setError] = useState(404);
useEffect(() => {
const url = "http://localhost:3000/user/";
const fetchData = async () =>{
Promise.all([
fetch(url + id),
fetch(url + id + "/activity"),
fetch(url + id + "/average-sessions"),
fetch(url + id + "/performance")
]).then(([responseGlobal, responseActivity, responseSessions, responsePerformance]) => Promise.all([responseGlobal.json(), responseActivity.json(), responseSessions.json(), responsePerformance.json(), responseGlobal.status
])).then(([responseGlobal, responseActivity, responseSessions, responsePerformance, statusError]) => {
setError(statusError);
setData({
globalInfo: responseGlobal,
activity: responseActivity,
averageSessions: responseSessions,
performance: responsePerformance
});
}).catch(error => {
throw new Error(error);
});
}
if(id != null){
fetchData();
}
}, [id])
return(
<DataContext.Provider value={{id, data, setID, error}}>
{children}
</DataContext.Provider>
)
}
每次您的子组件 APIChecker 调用 setID 时,这将触发父组件中的 useEffect,因为您已在依赖数组中传递了 id。 这反过来会多次调用 API。
useEffect(()=>{
/*your implementation*/
},[id]);
如果你只想调用一次,只需传递空数组作为依赖项,如下所示:
useEffect(()=>{
/*your implementation*/
},[]);