【问题标题】:React - Passing fetched data from API as props to componentsReact - 将从 API 获取的数据作为道具传递给组件
【发布时间】:2019-04-16 19:44:52
【问题描述】:

我正在尝试了解和学习如何将数据作为道具传递给其他组件以供使用。我正在尝试构建一个顶级层次结构,其中 API 请求在顶级类中发出,然后将结果传递给子组件以用作道具,然后在状态中使用。

问题是,当我传递结果时,我在子组件中得到 "Object Promise"。 如何访问作为 props 发送给子组件的数据?

您可以在我的 render() 方法中的 App.js 中看到,我创建了类 API 的组件并从 fetchData() 传递结果方法作为组件的参数。

在我的 API.js 类中,我使用了 console.log 来检查结果,但是 我从日志中得到的结果是:

第 5 行: {dataObject: Promise}

第 10 行:未定义

App.js:

import API from './API';

class App extends Component {

  componentDidMount(){
    this.fetchData();
  }


  fetchData(){
      const url = "https://randomuser.me/api/?results=50&nat=us,dk,fr,gb";
      return fetch(url)
          .then(response => response.json())
          .then(parsedJSON => console.log(parsedJSON.results))
          .catch(error => console.log(error));
  }

  render() {
    return (
      <div className="App">
        <API dataObject={this.fetchData()}/>
      </div>
    );
  }
}

export default App;

API.js

import React from 'react';

class API extends React.Component{
    constructor(props){
        console.log(props);
        super(props);
        this.state = {
            dataObj:props.dataObject
        };
        console.log(this.state.dataObject)
    }


    render() {
        return(
            <p>""</p>
        )
    }
}

export default API;

【问题讨论】:

    标签: javascript reactjs api


    【解决方案1】:

    您应该在componentDidMount 而不是render 中获取数据。 每次在 react.js 重新渲染 DOM 时,在 render 中获取数据会导致 API 请求重复。

    向 API 端点发出 GET 请求后,首先将数据解析为 javascript 对象,然后在组件内使用 this.setState将结果设置为 state。

    从那里,您可以将state 中保存的数据传递给render 函数中的子组件作为道具。

    例如:

    const App = (props) => 
        <ChildComponent />
    
    class ChildComponent extends React.Component {
    
        constructor(props){
            super(props);
            this.state = {
                results: []
            }
        }
        componentDidMount(){
            fetch('/api/endpoint')
                .then(res => res.json())
                .then(results => this.setState({results})
        }
    
        render(){
            return <GrandchildComponent {...this.state} />
        }
    
    }
    
    const GrandchildComponent = (props) => 
        <div>{props.results}</div>
    

    【讨论】:

    • 好的,我会尝试这种方法,但问题是在层次结构的顶层,我不希望类具有状态。在这种情况下,我不希望 App.js 有状态,我希望它是无状态的。只有子组件应该有状态
    • 这是一篇关于在 React 组件中使用 API 的精彩教程:robinwieruch.de/react-fetching-data
    • OK,然后将App设为功能性无状态组件,然后将所有API请求委托给子组件,子组件将API结果保存在状态。
    • 我的意思是我可以在顶层拥有一个状态,但这是 React 的做事方式吗?或者顶层应该始终是无状态的,只有孩子应该有状态?你的解决方案是什么意思?如何将 API 请求委托给子组件?
    • 我建议您将获取的结果保存在需要数据的组件的最大共同祖先的state 中。因此,如果您只需要 API 结果生成单个子组件,只需在那里处理请求,并将其存储在其状态中。这样你就可以拥有一个无状态的 App 组件(你创建这些组件的方式与创建普通 javascript 函数的方式相同,使用 props 作为唯一参数,并返回你想要呈现的任何内容,在这种情况下,你的组件使API 调用)。
    【解决方案2】:

    尝试把 App.js 改成这样:

    import API from './API';
    
    class App extends Component {
    
      componentDidMount(){
        this.fetchData();
      }
    
    
      fetchData(){
          const url = "https://randomuser.me/api/?results=50&nat=us,dk,fr,gb";
          return fetch(url)
              .then(response => response.json())
              .then(parsedJSON => this.setState({results: parsedJSON.results}))
              .catch(error => console.log(error));
      }
    
      render() {
        return (
          <div className="App">
            <API dataObject={this.state.results}/>
          </div>
        );
      }
    }
    
    export default App;
    

    这确保您获取componentDidMount 中的数据,现在它使用state 存储数据,然后将其传递到您的API 组件中。

    【讨论】:

    • 您是否对 App.js 类进行了任何更改?在我看来,我的和你的似乎没有区别?
    • 通过以这种方式将fetchData 作为道具传递,您会导致它在每次重新渲染组件时触发。
    • @RileySteeleParsons 抱歉,我想改变它,但取消了它。我已经更新了
    【解决方案3】:

    如果有人正在使用 Hooks 寻找答案,那么这可能会有所帮助。

    App.js

    import API from './API';
    
    function App(props) {
    
      const [result, setResult] = React.useState({});
    
      // similar to componentDidMount
      React.useEffect(() => {
        this.fetchData();
      }, []);
    
    
      fetchData() {
          const url = "https://randomuser.me/api/?results=50&nat=us,dk,fr,gb";
          fetch(url)
              .then(response => setResult(response.json()))
              .catch(error => console.log(error));
      }
      return (
          <div className="App">
            <API dataObject={result}/>
          </div>
        );
    }
    
    export default App;
    

    API.js

    import React from "react";
    
    function API(props) {
      
      const [result, setResult] = React.useState(props.dataObject);
    
      React.useEffect(() => {
        setResult(result);
      }, [result]);
    
      return <p>{result}</p>;
    }
    
    export default API;
    

    希望对您有所帮助!如果有任何不正确的地方,请告诉我。

    【讨论】:

    • 所以你创建一个容器组件只是为了保存数据作为道具?有点临时/hacky上下文排序的东西?
    猜你喜欢
    • 2021-05-11
    • 2018-08-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 2020-03-12
    相关资源
    最近更新 更多