Reputation: 141
I'm pretty new to React (coming from Angular 1), and have been playing around with it somewhat. I have a test script that loops through a multidimensional object, and binds it to the dom.
I then add a new item to the object wrapped in a setTimeout. Is calling the ReactDOM.render below that the best way to rerender the React component?
var items = [
{ name: 'Matt', link: 'https://google.com' },
{ name: 'Adam', link: 'https://bing.com' },
{ name: 'Luke', link: 'https://yahoo.com' },
{ name: 'John', link: 'https://apple.com' }
];
var RepeatModule = React.createClass({
getInitialState: function() {
return { items: [] }
},
render: function() {
var listItems = this.props.items.map(function(item) {
return (
<li key={item.name}>
<a className='button' href={item.link}>{item.name}</a>
</li>
);
});
return (
<div className='menu'>
<h3>The List</h3>
<ul>
{listItems}
</ul>
</div>
);
}
});
ReactDOM.render(<RepeatModule items={items} />, document.getElementById('react-content'));
setTimeout(function() {
var newline = { name: 'Added item', link: 'https://amazon.com' };
items.push(newline);
ReactDOM.render(<RepeatModule items={items} />, document.getElementById('react-content'));
}, 2000);
Much appreciated :)
Upvotes: 0
Views: 296
Reputation: 523
You could use the react state
working demo: http://codepen.io/anon/pen/WGyamK
var RepeatModule = React.createClass({
getInitialState: function() {
return { items: [
{ name: 'Matt', link: 'https://google.com' },
{ name: 'Adam', link: 'https://bing.com' },
{ name: 'Luke', link: 'https://yahoo.com' },
{ name: 'John', link: 'https://apple.com' }
] }
},
componentDidMount() {
var _this = this
setTimeout(function() {
var newline = { name: 'Added item', link: 'https://amazon.com' };
_this.setState({items: _this.state.items.concat(newline)});
}, 2000);
},
render: function() {
var listItems = this.state.items.map(function(item) {
return (
<li key={item.name}>
<a className='button' href={item.link}>{item.name}</a>
</li>
);
});
return (
<div className='menu'>
<h3>The List</h3>
<ul>
{listItems}
</ul>
</div>
);
}
});
ReactDOM.render(<RepeatModule />, document.getElementById('react-content'));
That being said, you should use some library trigerring the rerender for you. You are coming from Angular, so firstly you need to know that React is not a whole framework like angular, but just the "V in MVC".
I use react in combination with redux. Check out https://github.com/reactjs/redux for more.
There are some good boilerplate codes out there to get started quickly. I like this https://github.com/davezuko/react-redux-starter-kit
Hope you find this useful.
Upvotes: 0
Reputation: 7468
React docs advise to place async calls in the componentDidMount
method.
Load Initial Data via AJAX
Fetch data in componentDidMount. When the response arrives, store the data in state, triggering a render to update your UI.
https://facebook.github.io/react/tips/initial-ajax.html
Here is a demo: http://codepen.io/PiotrBerebecki/pen/KgZGao
const App = React.createClass({
getInitialState: function() {
return {
items: [
{ name: 'Matt', link: 'https://google.com' },
{ name: 'Adam', link: 'https://bing.com' },
{ name: 'Luke', link: 'https://yahoo.com' },
{ name: 'John', link: 'https://apple.com' }
]
};
},
componentDidMount: function () {
setTimeout(() => {
this.setState({
items: [
...this.state.items,
{ name: 'Added item', link: 'https://amazon.com' }
]
});
}, 2000);
},
render: function() {
var listItems = this.state.items.map(function(item) {
return (
<RepeatModule key={item.name} href={item.link} itemName={item.name} />
);
});
return (
<div>
<h3>The List</h3>
{listItems}
</div>
);
}
});
const RepeatModule = React.createClass({
render: function() {
return (
<div className='menu'>
<ul>
<li>
<a className='button' href={this.props.href}>{this.props.itemName}</a>
</li>
</ul>
</div>
);
}
});
ReactDOM.render(
<App />,
document.getElementById('app')
);
Upvotes: 1
Reputation: 21846
Wrap the RepeatModule within a parent component. Items should be part of the state. Have a button to add new item. On click of the new item, pass the item details to the parent component. The parent component should update the state.
Your code won't work because you are pushing item to items. You should slice it before pushing it. React checks for props / state change using the === operator.
setTimeout(function() {
var newline = { name: 'Added item', link: 'https://amazon.com' };
var newItems = items.slice();
newItems.push(newline);
ReactDOM.render(<RepeatModule items={newItems} />, document.getElementById('react-content'));
}, 2000);
Upvotes: 0