我正在使用React.js和Wordpress REST API做一个项目。一直以来,无论何时安装组件,我都一直使用axios从API获取数据。这意味着每次我渲染一个必须显示一些数据的组件时,我都会发出API请求。该项目正在扩大,我意识到这种做事方式不是最好的。
我应该如何处理这个问题?我应该使用Redux吗?我认为Redux在这方面是过大的,因为我不会修改数据,只会显示它。我应该使用React Context API吗?
如果需要任何代码,我会添加。
答案 0 :(得分:1)
我认为redux是保持项目可伸缩性和组织良好的最佳解决方案,但是如果您不想使用它,则可以尝试使用上下文,请记住这意味着您必须在api中调用api。高级组件。
以下是带有上下文定义的应用程序组件示例:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export const DataContext = React.createContext({})
const App = () => {
const [apiResponse, setApiResponse] = useState({});
useEffect(() => {
axios.get(endPoint).then(response => setApiResponse(response))
},[]);
return (
<DataContext.Provider value={apiResponse}>
<YourAppContent />
</DataContext.Provider>
);
}
export default App
每次您需要获取API数据:
import React, { useContext } from 'react';
import Card from './Card';
import { DataContext } from '../App';
const UserCard = () => {
const data = useContext(DataContext);
const { user } = data || {};
return <Card>{user.fullName}</Card>
}
export default UserCard
答案 1 :(得分:1)
如果您的应用程序状态相对简单,并且只想显示数据。我认为使用Context API是合适的方法。
用于简单状态
import React, { useState, useEffect, useContext, createContext } from 'react';
// some sort of libs that fetchs data for you.
import FetchService from './util/FetchService';
const OrderInfoContext = createContext();
// This is a helper component that generates the Provider wrapper
function OrderInfoProvider(props) {
// We will persist API payload in the state so we can assign it to the Context
const [orders, setOrders] = useState([]);
// We use useEffect to make API calls.
useEffect(() => {
async function fetchData() {
// This is just a helper to fetch data from endpoints. It can be done using axios or similar libraries
const orders = await FetchService
.get('/v1/registry/orders');
setOrders(orders);
}
fetchData();
});
//we create a global object that is avaibvale to every child components
return <OrderInfoContext.Provider value={[orders, setOrders]} {...props} />;
}
// Helper function to get Context
function useOrderInfo() {
const context = useContext(OrderInfoContext);
if (!context) {
throw new Error('useOrderInfo must be used within a OrderInfoProvider');
}
return context;
}
export { OrderInfoProvider, useOrderInfo };
用于稍微复杂的状态
随着您的应用变得越来越复杂。您仍然可以通过useReducer
钩子使用相同的方法
// reducer returns the next state based on the action passed in
const reducer = (state, action) => {
switch (action.type) {
case INITIAL:
return [];
case FETCH_ORDER:
return action.payload;
case ADD_ORDER:
return [...state, action.payload];
default:
throw new Error();
}
};
// This is a helper component that generate the Provider wrapper
function OrderInfoProvider(props) {
// We will persist API payload in the state so we can assign it to the Context
const [orders, dispatch] = useReducer(reducer, []);
const addOrderInfo = (data) => { addOrders(dispatch, data); };
async function fetchOrders() {
const data = await ApiService
.get('/v1/registry/orders');
dispatch({
type: FETCH_ORDER,
payload: data
});
}
useEffect(() => {
fetchOrders();
}, []);
// we create a global object that is available to every child components
return <OrderInfoContext.Provider value={[orders, dispatch]} {...props} />;
}
用于复杂状态
您绝对应该考虑使用Redux作为其他建议的答案。 Redux开发工具可以为您节省大量调试时间。
参考
我从我之前写的几篇文章中获取了代码。您可能在那里可以找到更好的解释。
https://tech.zola.com/practical-use-cases-of-react-context-and-hooks-a9f62815e38d