簡體   English   中英

React Reuse獲取整個組件中的JSON數據

[英]React Reuse Fetch JSON data throughout components

嗨,我是React的新手,並在我的整個項目中學習了可重用功能。

我想獲取我的JSON數據,但不必每次都在組件中調用它。

App.js

import React, { Component } from 'react';
import { Route, NavLink, HashRouter } from "react-router-dom";

import logo from '../assets/logo.png';
import './app.css';

import About from "../about/about";
import Services from "../services/services";
import Testimonials from "../testimonials/testimonials";
import Contact from "../contact/contact";

class App extends Component {
constructor(props) {
    super(props);
    this.state = {
       items : []
    };
}
componentDidMount(){
  this.getItems();
}
getItems(){
  fetch('./data/data_arr.js')
  .then(results => results.json())
  .then(results => this.setState({'items': results}));
}
render() {
 return (
  <HashRouter>
    <div className="container">
      <div className="header">
        <div className="App-logo"><NavLink exact to="/"><img src={logo} alt="logo" /></NavLink></div>
        <nav className="Nav-Desktop">
        {this.state.items.map((item, index) => (
          <div key={index}>
          {
            item.links.map((link, i) => (
            <NavLink key={i} exact to={link.url}>{link.text}</NavLink>
          ))}
          </div>
        ))}
        {
          this.state.items.map((item, index) => {
            return <div key={index}><a href={item.mainContact.phoneHref + item.mainContact.phone}><i className="fa fa-phone"></i><strong> {item.mainContact.phone}</strong></a></div>
          })
        }
        </nav>
      </div>
      <main className="content">
         <Route exact path="/" component={About}/>
         <Route path="/services" component={Services}/>
         <Route path="/testimonials" component={Testimonials}/>
         <Route path="/contact" component={Contact}/>
      </main>
      {this.state.items.map((item, index) => {
        return <footer key={index}>&copy; Copyright {item.title} {(new Date().getFullYear())}</footer>
      })
      }
    </div>
    </HashRouter>
    );
  }
}
export default App;

我已經成功映射了數據並顯示了數據,但是我還有其他包含此代碼段的文件

constructor(props) {
    super(props);
    this.state = {
       items : []
    };
}
componentDidMount(){
  this.getItems();
}
getItems(){
  fetch('./data/data_arr.js')
  .then(results => results.json())
  .then(results => this.setState({'items': results}));
}

我試過像這樣在helper.js文件中導出getItems(),然后import { getItems } from '../helpers/helpers';導入文件import { getItems } from '../helpers/helpers'; 但是,代碼無法正常工作,並被卡在Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined

export function getItems() {
    fetch('./data/data_arr.js')
    .then(results => results.json())
    .then(results => this.setState({'items': results}));
}

如果有人可以給我指出錯誤的正確方法,那將很有幫助。 干杯

當您要重用數據而不是一次又一次地調用fetch時,需要了解兩件事

  1. 請在最頂層的組件(即父組件)中獲取調用,並將數據傳遞給所有子組件,子組件再傳遞給子組件,但是請記住,這對您來說很忙。 當您構建小型應用程序時(例如最多50個組件),這種方法非常有用。 但是,當您的應用程序變大時,這不是在組件之間重用數據的推薦方法。

  2. 使用Redux狀態管理庫來實現跨組件的數據可重用性。 這就像您的應用程序的集中存儲。 如今,這幾乎在每個React應用中都使用。 使用Redux,您可以在父組件中進行操作調用,該操作實際上將獲取數據並將其傳遞給reducer。 因此,現在reducer將在Redux存儲中設置數據。 現在,通過使用state.get從Redux存儲中獲取數據,可以在每個組件中訪問數據。 因此,您可以調用redux操作,例如this.props.getItems();。 無論您在哪里需要組件中的數據,組件mapStateToProps都會使這些數據作為道具可供您的組件使用

如何從Redux存儲中獲取數據?

在component中定義一個函數mapStateToProps,並使用state.get從Redux存儲中獲取數據並在函數中返回。 傳遞mapStateToProps連接方法。 您將把組件連接到名為connect的Redux HOC組件。 此connect方法接受操作和Redux狀態,並使它們作為道具可用於組件。

關於你的問題

   Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined

之所以會出現此問題,是因為導出的getItems函數內部不提供此功能。

解決此問題所需要做的就是將此作為參數傳遞給getItems函數

注意:這是當前上下文

 import { getItems } from '../helpers/helpers';

 componentDidMount(){
     getItems(this);
 }

helpers.js:

 the below function is treated as a normal JavaScript function. This function no wr belongs the component to bind it in component constructor. But in order to play with the state of the component you need to pass the component context this. But this is old way, now a days we all use Redux to avoid these old concepts

 export function getItems(this) {
      fetch('./data/data_arr.js')
.then(results => results.json())
.then(results => this.setState({'items': results}));
      }

這樣,您可以重用此函數並執行setState。

但是請記住,當您的應用程序將來變得越來越大時,這些解決方案將變得復雜。 因此,我建議您從現在開始使用Redux狀態管理庫,以避免將來出現繁忙遷移:)

如果有錯字錯誤,請問我是因為我在用手機接聽電話。

您需要將上下文傳遞給您的輔助函數。 考慮到您仍然從助手中導入功能,在componentDidMount上,它可能像這樣:

componentDidMount(){
 getItems.call(this);
}

抓取如此出色,跨組件共享數據可以采用很多路徑,您可以研究以下兩個主要路徑:

  1. 父狀態保存數據,通過道具傳遞數據
  2. 商店(Mobx,Redux)保存數據,然后根據需要將其注入到組件中

我不會為您提供有關如何全部完成操作的教程,但我認為第一種選擇現在最適合您。

如果您的組件使用相同的數據,則理論上它們在結構上應具有相同的父組件:

Page Component (Overarching component, lays out the page structure)
 Header
 Component 1
 Component 2
 Footer

因此,您將在Page component的安裝上進行此調用,並將this.state.items作為prop傳遞給需要它的其他組件...商店具有類似的過程,它們只是保存了props的雙重處理:)

由於您要在getItems()方法中訪問/修改狀態,因此應將其綁定到構造函數中,如下所示:

constructor() {
    super(props);
    this.state = {
      items : []
    };
    this.getItems = this.getItems.bind(this);
}

或者您可以簡單地使用arrow函數聲明它,因此不必綁定它:

getItems = () => {
   // some codes here
}

另一件事,唯一可以訪問/修改組件狀態的是它自己的方法。 如果要在自身之外使用它,則將這些組件作為子項導入到組件內部,然后將getItems()方法作為prop傳遞。

  render() {
  return (
    <HashRouter>
      <div className="container">
        // some other codes
        <ChildComponent getItems={this.getItems} />
      </div>
      </HashRouter>
    );
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM