简体   繁体   English

React - 如何将返回的数据从导出函数传递给组件?

[英]React - How to pass returned data from an exported function to a component?

How can I pass data I receive from a get request pass over to a component?如何将从 get 请求接收到的数据传递给组件? Whatever I tried wouldn't work but my thinking was as the code below shows.. Thanks!无论我尝试什么都行不通,但我的想法如下面的代码所示。谢谢!

    export function data() {
        axios.get('www.example.de')
            .then(function(res) {
                return res.data
            })
            .then(function(data) {
                this.setState({
                    list: data
                })
            })
    }

    import {data} from './api.js';

    class Test extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                list: ""
            };
        }

        componentWillMount() {
            data();
        }
        render() {
            return <p > this.state.list < /p>
        }
    }

You call this.setState inside of data()->then callback, so this is context of the then callback function.您在data()->then回调中调用this.setState ,因此thisthen回调函数的上下文。 Instead you should use arrow functions (it does not have its own context) and pass component's this to data function using call相反,您应该使用箭头函数(它没有自己的上下文)并使用call将组件的this传递给data函数

export function data() {
    axios.get('www.example.de')
        .then(res => res.data)
        .then(data => {
            this.setState({
                list: data
            })
        })
}

import {data} from './api.js';

class Test extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            list: ""
        };
    }

    componentWillMount() {
        data.call(this);
    }
    render() {
        return <p > this.state.list < /p>
    }
}

However, your data services must not know about setState and, event more, expect passing this from react component.但是,您的数据服务不能知道setState并且更重要的是,期望从 React 组件传递this Your data service must be responsible for retrieving data from server, but not for changing component state, see Single responsibility principle .您的数据服务必须负责从服务器检索数据,但不负责更改组件状态,请参阅 单一职责原则 Also, your data service can be called from another data service.此外,可以从另一个数据服务调用您的数据服务。 So your data service should return promise instead, that can be used by component for calling setState .因此,您的数据服务应该返回 promise,组件可以使用它来调用setState

   export function data() {
       return axios.get('www.example.de')
           .then(res => res.data)
   }

and then接着

componentWillMount() {
    data().then(data=>{
        this.setState({
            list: data
        })
    });
}

your api shouldn't know anything about your component, you can easily do this with callback , like so -您的api不应该对您的组件一无所知,您可以使用callback轻松做到这一点,就像这样 -

export function data(callback) {
    axios.get('www.example.de')
        .then(res => callback({ data: res.data }))
        .catch(err => callback({ error: err }));
}

By doing this you can easily unit test your api通过这样做,您可以轻松地对您的api进行单元测试

So in your Test component, you simply do -所以在你的Test组件中,你只需要做 -

componentWillMount() {
  data(result => {
    const { data, error } = result;
    if (error) {
      // Handle error
      return;
    }

    if (data) {
      this.setState({ list: data });
    }
  });
}

Your request is a promise so you can simply return that from the imported function and use the eventual returned result of that within the component.您的请求是一个承诺,因此您可以简单地从导入的函数中返回它,并在组件中使用最终返回的结果。 You only want to be changing the state of the component from within the component.您只想从组件内部更改组件的状态。

export function getData(endpoint) {
  return axios.get(endpoint);
}

Note I've changed the name of the function to something more "actiony".请注意,我已将函数的名称更改为更“actiony”的名称。

import { getData } from './api.js';

class Test extends React.Component {
  constructor(props) {
    super(props);

    // Your state is going to be an array of things, so
    // initialise it with an array to spare confusion
    this.state = { list: [] };
  }

  // I use ComponentDidMount for fetch requests
  // https://daveceddia.com/where-fetch-data-componentwillmount-vs-componentdidmount/
  componentDidMount() {

    // We've returned a promise from `getData` so we can still use the
    // promise API to extract the JSON, and store the parsed object as the
    // component state
    getData('www.example.de')
      .then(res => res.data)
      .then(list => this.setState({ list }))
  }
}

Your external function doesn't have the correct context of this , so you'll need to call it with the correct context from within the component:您的外部函数没有this的正确上下文,因此您需要使用组件内的正确上下文调用它:

componentWillMount() {
    data.call(this);
}

However, inside the API call, it still won't have the correct this context, so you can set a variable to point to this inside the data() function:但是,在 API 调用中,它仍然没有正确的this上下文,因此您可以在 data() 函数中设置一个变量来指向 this:

export function data() {
  let that = this;
  axios('http://www.url.com')
    .then(function(res) {
      return res.data
    })
    .then(function(data) {
      that.setState({
        list: data
      })
    })
}

Details of the this keyword this 关键字的详细信息

However, it's generally considered better practice to only handle your state manipulation from with the component itself, but this will involve handling the asynchronous nature of the GET request, perhaps by passing in a callback to the data() function.然而,通常认为更好的做法是只处理组件本身的状态操作,但这将涉及处理 GET 请求的异步性质,可能通过将回调传递给data()函数。

EDIT: Updated with asynchronous code编辑:更新为异步代码

//api.js
data(callback){
  axios.get('www.url.com')
    .then(res => callback(res));
}

//component.jsx
componentWillMount(){
  data(res => this.setState({list: res}));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM