nourdine
nourdine

Reputation: 7597

How do you create a react component that loads data by itself?

I need to create an element that, when rendered, loads its own data and displays it. I wrote something like this:

export default class MyComponent extends React.Component {

   constructor() {
      super();
      this.state = {
         content: "Loading..." 
      };
   }

   render() {
      Data.singleton().load(0, 100, "desc").then((function(data) {
         this.setState({
            content: {JSON.stringify(data, null, 3)}
         });
      }).bind(this));  
      return <pre>{this.state.content}</pre>             
   }
}

Now, this works but the react documentation clearly states that:

The render() function should be pure, meaning that it does not modify component state

So I was wondering what's the best design pattern for this kind of needs.

p.s.: I know I could load the data in the containing element and pass it in to MyComponent using props. I am also aware that that seems "the way" to go with react but I was wondering if there are other legitimate ways.

Thanks

Upvotes: 2

Views: 296

Answers (3)

omarjmh
omarjmh

Reputation: 13896

Here is an example: JSFiddle

This should be handled in componentDidMount (note, I'm using a setTimeout, to 'simulate' the async call):

class Main extends React.Component{
    constructor(props){
    super(props);
    this.state = {
    data: 'Loading...'
    }
  }
  componentDidMount() {
   console.log('Mounted');
   setTimeout(() => {
        this.setState({
      data: 'set after waiting 2 seconds'
      })
   }, 2000)
  }
  //
  render() {
    return (
        <div>{this.state.data}</div>
    );
  }
}

Upvotes: 2

Abiodun
Abiodun

Reputation: 467

Since its recommended to have your ajax method in the componentDidMount https://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmount You can structure your react component like this

export default class MyComponent extends React.Component {

   constructor() {
      super();
      this.state = {
         content: "Loading..." 
      };
   }
   componentDidMount(){
      Data.singleton().load(0, 100, "desc").then((data)=> {
         this.setState({
            content: {JSON.stringify(data, null, 3)}
         });
      }); 
     }

   render() {

      return <pre>{this.state.content}</pre>             
   }
}

Upvotes: 0

Christine Cha
Christine Cha

Reputation: 525

It looks like all you need to do is toss that function into componentDidMount or componentWillMount, like so:

componentDidMount() {
  // state-altering logic
}

render() {
  return <pre>{this.state.content}</pre>             
}

https://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount

Upvotes: 0

Related Questions