slava_slava
slava_slava

Reputation: 666

How to set dynamically data into component from outside to inside?

I will need set dynamically data from component, like this:

var dynamicData = 0;
setInterval(()=>{
    dynamicData = (Math.random() * 100).toFixed(0); // ???
}, 3000);

var Hello = React.createClass({
  render: function() {
    return <h2>{this.props.test}</h2>;
  }
});

ReactDOM.render(
  <Hello test={dynamicData} />,
  document.getElementById('container')
);

props 'test' is not dynamically - after change setTimeout value into component didn't change. Maybe it has other best way to do this? How to add dynamically data into component, which changed outside the component?

Upvotes: 1

Views: 67

Answers (2)

Manolo Santos
Manolo Santos

Reputation: 1913

You should call the ReactDOM.render method again inside the setInterval callback. It looks inefficient, but React is clever enough to reuse the mounted component and update it with the new props.

From the React API documentation:

If the ReactElement was previously rendered into container, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React component.

var dynamicData = 0;
setInterval(()=>{
  dynamicData = (Math.random() * 100).toFixed(0); // ???
  ReactDOM.render(
    <Hello test={dynamicData} />,
    document.getElementById('container')
  );
}, 1000);

var Hello = React.createClass({
  render: function() {
    return <h2>{this.props.test}</h2>;
  }
});

ReactDOM.render(
  <Hello test={dynamicData} />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="container"/>

Upvotes: 3

DarkKnight
DarkKnight

Reputation: 5944

You can use a global event emitter, and pass it by props, the component listens to changes and updates its state.

const dynamicData = new EventEmitter();
setInterval(()=>{
    let newValue = (Math.random() * 100).toFixed(0);
    dynamicData.emit('change', newValue)
}, 3000);

var Hello = React.createClass({
  getInitialState: () => ({test: 0}),
  handleChange: function(newValue) {
    this.setState({test: newValue})
  },
  componentDidMount: function() {
    this.props.test.on('change', this.handleChange)
  },
  componentWillUnmount: function() {
    this.props.test.removeListener('change', this.handleChange)
  },
  render: function() {
    return <h2>{this.state.test}</h2>;
  }
});

ReactDOM.render(
  <Hello test={dynamicData} />,
  document.getElementById('container')
);
<script src="https://npmcdn.com/[email protected]/EventEmitter.min.js"></script>
<div id="container">
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Upvotes: 1

Related Questions