Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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? 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>
        }
    }
like image 405
javascripting Avatar asked Dec 14 '22 21:12

javascripting


2 Answers

You call this.setState inside of data()->then callback, so this is context of the then callback function. Instead you should use arrow functions (it does not have its own context) and pass component's this to data function using call

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. 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.

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

and then

componentWillMount() {
    data().then(data=>{
        this.setState({
            list: data
        })
    });
}
like image 93
Maxim Kuzmin Avatar answered Dec 21 '22 10:12

Maxim Kuzmin


your api shouldn't know anything about your component, you can easily do this with callback, like so -

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

So in your Test component, you simply do -

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

    if (data) {
      this.setState({ list: data });
    }
  });
}
like image 42
grgmo Avatar answered Dec 21 '22 09:12

grgmo