Reputation: 13
Why is an empty array created when rendering this JSON array? See attached screenshot I assume the constructor is just initiating it with a null value and filling it at a later point.
New to Javascript + React and just want to make sure I am understanding what is happening. I will also accept critique on the garbage code that is below. Codepen link
class Jobs extends React.Component {
render() {
const jobs = this.props.jobs;
console.log(jobs);
const formattedJobs = jobs.map((job) =>
<ul key={job.id}>
<div class="company">{job.company_name}</div>
<div class="title">{job.title}</div>
</ul>
);
return(
<div>{formattedJobs}</div>
);
}
}
class App extends React.Component {
constructor() {
super();
this.state={
jobs:[]
}
var myUrl = "https://codepen.io/jobs.json";
fetch(myUrl)
.then((response) => response.json())
.then((json) => this.setState({jobs: json.jobs}));
}
render() {
return (
<div className="app">
<div className="header">
<h1 id="header-title">Job Postings</h1>
</div>
<div className="content">
<Jobs jobs={this.state.jobs}/>
</div>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
Upvotes: 1
Views: 3373
Reputation: 7438
class
with className
as first one is restricted word in JSX
ul
can only contains li
childs - not div
key
property when you iterate over collectionerror
and support itApp
or Jobs
class Jobs extends React.Component {
render() {
const { jobs } = this.props;
const formattedJobs = jobs.map(job =>
<ul key={job.id}>
<li className="company">{job.company_name}</li>
<li className="title">{job.title}</li>
</ul>
);
return <div>{formattedJobs}</div>;
}
}
Jobs.defaultProps = {
jobs: []
};
class App extends React.Component {
constructor() {
super();
this.state = {
jobs: []
};
}
componentDidMount() {
fetch("https://codepen.io/jobs.json")
.then(response => response.json())
.then(response => {
if (!Array.isArray(response.jobs)) {
throw new Error(
`Expected response but got ${JSON.stringify(response.jobs)}`
);
} else {
return response.jobs;
}
})
.then(jobs => this.setState({ jobs }));
}
render() {
return (
<div className="app">
<div className="header">
<h1 id="header-title">Job Postings</h1>
</div>
<div className="content">
<Jobs jobs={this.state.jobs} />
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Upvotes: 1
Reputation: 2771
always use fetch statements in ComponentDidMount as it is called just after your component is rendered for the very first time
ComponentDidMount {
fetch(myUrl)
.then((response) => response.json())
.then((json) => this.setState({jobs: json.jobs}));
}
Upvotes: 1
Reputation: 3348
You are getting the jobs from an ajax request wich is async. Thats why the initial value is an empty array.
App.render is executed before your ajax request is finished and thats why you are not givin any job to the Jobs component. Once the ajax is finished, the jobs array is filled with the results and sendeded to the Jobs component to render the results of that ajax request.
Upvotes: 1