处理来自API调用和呈现React组件的数据的最佳做法

时间:2019-05-29 23:15:24

标签: reactjs axios

我对React有点陌生,并在我的React / Redux / Firebase PWA中寻找针对特定情况的最佳实践。现在,我关心的部分实质上是Yelp API的包装。

我有一个主要组件,可以根据应用程序其他位置收到的用户首选项在加载时查询Yelp API(在componentDidMount内部)。该组件还查询带有用户输入的表单提交的API。它遍历两者的数据,并将props传递给子组件。该视图看起来像是从API接收到的所有业务的列表。这是一个示例:

"businesses": [
    {
      "rating": 4,
      "price": "$",
      "phone": "+14152520800",
      "id": "E8RJkjfdcwgtyoPMjQ_Olg",
      "alias": "four-barrel-coffee-san-francisco",
      "is_closed": false,
      "categories": [
        {
          "alias": "coffee",
          "title": "Coffee & Tea"
        }
      ],
      "review_count": 1738,
      "name": "Four Barrel Coffee",
      "url": "https://www.yelp.com/biz/four-barrel-coffee-san-francisco",
      "coordinates": {
        "latitude": 37.7670169511878,
        "longitude": -122.42184275
      },
      "image_url": "http://s3-media2.fl.yelpcdn.com/bphoto/MmgtASP3l_t4tPCL1iAsCg/o.jpg",
      "location": {
        "city": "San Francisco",
        "country": "US",
        "address2": "",
        "address3": "",
        "state": "CA",
        "address1": "375 Valencia St",
        "zip_code": "94103"
      },
      "distance": 1604.23,
      "transactions": ["pickup", "delivery"]
    },
    // ...
  ],

如前所述,主要组件将数据向下传递到子组件,该子组件呈现列出的每个单个对象。该子组件还基于每个业务的ID创建到另一个组件的链接。现在,该另一组件只是与一个单独的子组件完全相同的外观,只是在不同的URL上。例如,主要组件是“ / venues”,而企业的单个页面将是“ / venue / E8RJkjfdcwgtyoPMjQ_Olg”。数据从Redux状态(即HOC)中提取出来,并过滤掉以找到该ID。

我遇到的问题是在企业的单个页面上刷新页面时,Redux状态被清除,因此无法正确呈现数据。为了尝试解决此问题,我尝试让服务人员缓存所需的所有内容,但这不起作用。刷新最终仅显示我创建的加载页面,因为它没有进行调用(这是预期的-不想这样做),也没有从缓存中提取数据。

是否有更好的方法可以在刷新后将数据一直传输到各个业务组件?还是更好的方法来缓存整个页面/ API响应,以便在刷新时可以正确呈现?

我想我可以将其扩展到该特定业务的API,但我试图避免这种情况。

2 个答案:

答案 0 :(得分:0)

您尝试过localStorage吗?有一个redux middleware for it。看起来像这样:

import {createStore, compose} from 'redux';
import persist from 'redux-localstorage';

const store = createStore(reducer, compose(...otherMiddleware, persist(['apiResponses'])))

这将使您的redux状态的"apiResponses"部分在浏览器重新加载后仍然存在。

答案 1 :(得分:0)

我记得Yelp API有一个端点,您可以在其中获取单个业务的详细信息。也就是说,您应该为自己的单个业务页面设置动态路线;例如/businesses/:id。然后,您可以在路线道具中访问此查询参数,然后从那里获取该特定业务的数据。

类似这样的东西:

class IndividualBusiness extends Component {
  // ...

  componentDidMount() {
    fetchBusinessById(this.props.match.id).then(setState(...))
    // ...
  }

  // ...
}

路线看起来像这样:

<Route exact path="/businesses/:id" render={(routeProps) => <IndividualBusiness {...routeProps} />}/>

但是什么时候Redux存储中已经有数据呢?很简单,只需在您的componentDidMount()中添加控制流即可。