calbertts
calbertts

Reputation: 1513

Refs in dynamic components with ReactJS

I'm facing a issue and I haven't found any documentantion related.

This is my component's render method:

render()
{
  return (
    <div refs="myContainer">
    </div>
  );
}

Additionally I have a method to get data from my Java server:

getAsyncData()
{
  $.get('...URL...')
    .done(function(response) {
      var list = JSON.parse(response); // This is an objects array
      var elementsList = [];

      list.forEach(function(item) {
        elementsList.push(<div ref={item.id}>{item.name}</div>);
      });

      React.render(elementsList, React.findDOMNode(this.refs.myContainer));
    });
}

In my componentDidMount method I just start the async method:

componentDidMount()
{
  this.getAsyncData();
}

So I'm getting this error from ReactJS:

Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's render method). Try rendering this component inside of a new top-level component which will hold the ref.

So this means that I'm not able to use my dynamic elements, additionally think that instead of a simple DIV I would have a complex component with methods within.

How can I deal this?

Thank you!

Upvotes: 1

Views: 6762

Answers (1)

Felix Kling
Felix Kling

Reputation: 816232

How can I deal this?

By writing the component how it is supposed to. Keep the data in the state. .render() is called when the state changes, updating the output.

Example:

var Component = React.createClass({
  getInitialeState() {
    return {items: []};
  },

  getAsyncData() {
    $.get(...).done(
      response => this.setState({items: JSON.parse(response)})
    );
  },

  render() {
    var list = this.state.items.map(
      item => <div key={item.id} ref={item.id}>{item.name}</div>
    );
    return <div>{list}</div>;
  }
});

That's what React is all about: Describing the output based on the data. You are not adding or removing elements dynamically, you update the state, rerender and let React figure out how reconcile the DOM.
However, it's unclear to me why you need a ref in this situation.

I recommend to read https://facebook.github.io/react/docs/thinking-in-react.html

Upvotes: 3

Related Questions