Pramod Pandey Pramod Pandey -4 years ago 94
React JSX Question

Clicking link not rendering dom in reactjs

First time data loads properly but when i click filter button like latest or top ajax is passing but view not getting updated. I am not sure what is wrong in my code. I am new to react js.
Here is my example code :-

import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
import css from './css/bootstrap.css';
//import Search from './Search';

class FetchDemo extends React.Component {
constructor(props) {
super(props);

this.state = {
posts: [],
loading: true,
error: null
};
}

componentDidMount() {
// Remove the 'www.' to cause a CORS error (and see the error state)
axios.get(`https://newsapi.org/v1/articles?source=techcrunch&apiKey=789ea3cd651a49e5ba9fc2061d68138f`)
.then(res => {
//console.log(res.data);
// Transform the raw data by extracting the nested posts
const posts = res.data.articles;

//console.log(posts);

// Update state to trigger a re-render.
// Clear any errors, and turn off the loading indiciator.
this.setState({
posts,
loading: false,
error: null
});
//console.log(this.setState);
})
.catch(err => {
// Something went wrong. Save the error in state and re-render.
this.setState({
loading: false,
error: err
});
});
}

renderLoading() {
return <div>Loading...</div>;
}

renderError() {
return (
<div>
Uh oh: {this.state.error.message}
</div>
);
}

renderPosts() {
if(this.state.error) {
return this.renderError();
}

return (
<div className="row">
<First1/>
{this.state.posts.map(post =>
<div className="col-md-3">
<img src={post.urlToImage} className="img-responsive" />
<h2 key={post.id}>{post.title}</h2>
<p className="lead">
by {post.author}
</p>
<p><span className="glyphicon glyphicon-time"></span> Posted on {post.publishedAt}</p>
<p>{post.description}</p>
</div>
)}
</div>
);
}

render() {
return (
<div>
<h1>Top Stories</h1>
{this.state.loading ?
this.renderLoading()
: this.renderPosts()}
</div>
);
}
}

var First1 = React.createClass({
myClick: function(e){
alert(e.currentTarget.getAttribute("data-city"));
var city = e.currentTarget.getAttribute("data-city");
//alert('Show 1');
axios.get('https://newsapi.org/v1/articles?source=techcrunch&&sortBy='+city+'&apiKey=789ea3cd651a49e5ba9fc2061d68138f')
.then(res => {
//console.log(res.data);
// Transform the raw data by extracting the nested posts
const posts = res.data.articles;

//console.log(posts);

// Update state to trigger a re-render.
// Clear any errors, and turn off the loading indiciator.
//console.log(posts);
this.setState({
posts,
loading: false,
error: null
});

//console.log(this.setState);
})
.catch(err => {
// Something went wrong. Save the error in state and re-render.
this.setState({
loading: false,
error: err
});
});
},
render: function() {
return (<div>
<a onClick={this.myClick} data-city="latest"> Latest</a>
<a onClick={this.myClick} data-city="top"> Top</a>
</div>
);
}
});



// Change the subreddit to anything you like
ReactDOM.render(
<FetchDemo subreddit="reactjs"/>,
document.getElementById('root')
);


Here is link https://jsfiddle.net/69z2wepo/74393/

Answer Source

Issue is first time you are setting the data in parent component, and second time setting the data in child component, you need to update the state of parent component on click of top and latest.

Solution:

Pass a function from parent component and use that function to update the state once you get the response in child component, like this:

In Parent Component:

<First1 _updateState={this._updateState.bind(this)}/>

_updateState(posts){
     this.setState({
          posts,
          loading: false,
          error: null
      });
}

In Child Component:

myClick: function(e){
    ....
    .then(res => {

      this.props._updateState(res.data.articles) //pass data to parent component

    })
    ....
},

Check the fiddle for working solution: https://jsfiddle.net/ndg24fqc/

Note: In 1st component you are using es6 and in 2nd component you are using es5, try to use one thing either es6 or es5.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download