如何存储来自API的数据,以便可以在其他组件中进行访问

时间:2019-11-17 01:19:29

标签: reactjs wp-api

我正在使用React.js和Wordpress REST API做一个项目。一直以来,无论何时安装组件,我都一直使用axios从API获取数据。这意味着每次我渲染一个必须显示一些数据的组件时,我都会发出API请求。该项目正在扩大,我意识到这种做事方式不是最好的。

我应该如何处理这个问题?我应该使用Redux吗?我认为Redux在这方面是过大的,因为我不会修改数据,只会显示它。我应该使用React Context API吗?

如果需要任何代码,我会添加。

2 个答案:

答案 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

https://www.andrew-zheng.com/blog/use-reducer