I'm having this use case where there is a 'load more' button on the page to fetch more items from an API endpoint, and so I want these items to get appended to the DOM when they arrive. The thing is that the HTML page that is served by the web server comes with some extra list items (as seen below) within the same item-list
div container I mount my React component, with empty data/props, on page load.
<div class="item-list">
<div class="item-list__child-item"></div>
<div class="item-list__child-item"></div>
...
<div class="item-list__child-item"></div>
</div>
My assumption is that if I handle this in the ReactJS way, as soon as I fetch more items from the server (REST) and append those items to an 'itemList' state array, react will somehow replace all of the content that holds that 'item-list' div where the component was mounted on.
A quick workaround that I'm thinking would work and that it doesn't rely on the isomorphic stuff and pre-rendering the react component on the server, is to create a separate sibling div having the same div class name 'item-list' and adding an id attribute to mount the component on, so the resulting HTML would go like:
<div class="item-list">
<div class="item-list__child-item"></div>
<div class="item-list__child-item"></div>
...
<div class="item-list__child-item"></div>
</div>
<div class="item-list" id="react-component-name"></div>
Maybe there is a cleaner way to do it without getting into the isomorphic stuff, or maybe I'm not understanding the React concept and how it works. Anyways will appreciate any directions you may have on this.
componentDidMount() method As the name suggests, after all the elements of the page is rendered correctly, this method is called. After the markup is set on the page, this technique called by React itself to either fetch the data from An External API or perform some unique operations which need the JSX elements.
Mounting refers to the initial page loading when your React component is first rendered. From React documentation for Mounting: componentDidMount: Invoked once, only on the client (not on the server), immediately after the initial rendering occurs.
React renders HTML to the web page by using a function called render(). The purpose of the function is to display the specified HTML code inside the specified HTML element. In the render() method, we can read props and state and return our JSX code to the root component of our app.
OK, your question wasn't clear on this, but the data that is represented by what was generated in the HTML will be entirely different from the data that you will be getting via AJAX.
There's a simple solution to this. Instead of creating an entirely new DOM element that will be adjacent to your original DOM layout, what you will do is grab the data that was already there, store it into an array, and append the new data that you will grab via AJAX into that Array. This way, you will reap the benefit of React's DOM diffing. Why is it useful? Maybe you want to let the user sort the data, or interact with the data directly, while it will remain in full control of a parent React component.
So anyways, take a look at this fiddle: https://jsfiddle.net/x4jjry04/3/. It's based on Paul Booblic's fiddle.
var Page = React.createClass({
getDefaultProps: function () {
return {
items: []
}
},
getInitialState : function(){
return{
items : this.props.items
}
},
componentDidMount: function () {
// Mimics an AJAX call, but replace this with an actial AJAX call.
setTimeout(function () {
var dataFromAjax = ['one', 'two', 'three'];
this.setState({
items: this.state.items.concat(dataFromAjax)
});
}.bind(this));
},
addClick : function(){
this.state.items.push("more");
this.forceUpdate();
},
render : function(){
return <div>{this.state.items.map(function(item){return <div className="bla-bla-class">{item}</div>})}<br/><div onClick={this.addClick}>ADD</div></div>;
}
});
var elements = document.querySelectorAll('.item-list__child-item');
var initialvalues = Array.prototype.slice
.call(elements)
.map(function (div) {
return div.innerHTML;
});
React.render(<Page items={initialvalues} />, document.body);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With