Reputation: 3
I'm trying to render some data depending on the id that i pass in the url
, when i console.log()
the res.json
I have access to the data but I have no idea how to pass to the 'articleComponent'
const Articles = () => {
const query = (id) => {
fetch(`https://someurl.herokuapp.com/job/${id}`).then(res => console.log(res.json()))
}
const pathname = window.location.pathname.split('/');
const job_id = pathname[pathname.length - 1];
const job = query(job_id);
let position_name;
let workplace_name;
console.log(job_id)
if (job) {
position_name = position_name;
workplace_name = workplace_name;
}
return (
<ArticleComponent
position_name={position_name}
workplace_name={workplace_name}
/>
);
};
export default Articles
the console.log()
is returning 'pending but i can see all the object'
i have access to this component when i click this link:
<Link
className="link-apply"
to={{pathname: `/job/${job._id}`,
state: job
}}>
<p className="place">{job.workplace_name}</p>
<p className="location-job">{job.location}</p>
</Link>
Upvotes: 0
Views: 2122
Reputation: 1228
Hi @Erwin,
Here is the working example for your query. Checkout the CodeSandbox - [https://codesandbox.io/s/mystifying-wave-qxrnp][1]
Just replace the API Endpoint with your desired one. Hope this helps!
import React from "react";
import ReactDOM from "react-dom";
import ArticleComponent from "./ArticleComponent";
import "./styles.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: undefined
};
}
componentDidMount() {
const pathname = window.location.pathname.split("/");
const job_id = pathname[pathname.length - 1];
console.log(job_id);
fetch("https://jsonplaceholder.typicode.com/todos/1")
.then(response => response.json())
.then(json => this.setState({ data: json }));
}
render() {
return this.state.data ? (
<ArticleComponent data={this.state.data} />
) : (
"Loading"
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Upvotes: 0
Reputation: 1208
You have to separate loading logic and render. In your case you are using Component function, you should
Create state for your data with useState(null), where null is initial state
Use useEffect to start fetching data on component mount, where [] as second argument inform react what your useEffect not depends on any value and should run only once on component mount
import React, { useEffect, useState } from 'react';
const query = async (id, onFetchData) => {
const res = await fetch(`https://someurl.herokuapp.com/job/${id}`);
const data = await res.json();
onFetchData(data);
}
const getJobId = () => {
const pathname = window.location.pathname.split('/');
return pathname[pathname.length - 1];
}
const Articles = () => {
const [job, setJob] = useState(null);
useEffect(() => {
query(getJobId(), setJob);
} ,[]);
return <>{
job
? <ArticleComponent
position_name={job.position_name}
workplace_name={job.workplace_name}
/>
: <span>loading...</span>
}</>
};
export default Articles
Upvotes: 0
Reputation: 1322
You're not doing anything with the response of the fetch call.
When a React component is a functional component (as opposed to a class component), the function itself is the render function. This is a synchronous function, so you can't just have an async call in the function body.
For example, when the component enters the componentDidMount
lifecycle hook, you can call the fetch function, and whenever it returns, you can store the result in the component state (use setState
for class component or the useState
hook if it's a functional component).
So:
class Articles extends React.Component {
state = {
data: undefined
};
componentDidMount() {
const id = "some value";
fetch(`https://someurl.herokuapp.com/job/${id}`)
.then(res => res.json())
.then(response => this.setState({ data: response }));
}
render() {
const pathname = window.location.pathname.split('/');
const job_id = pathname[pathname.length - 1];
const job = query(job_id);
let position_name;
let workplace_name;
console.log(job_id)
if (job) {
position_name = position_name;
workplace_name = workplace_name;
}
return (
<ArticleComponent
data={this.state.data}
position_name={position_name}
workplace_name={workplace_name}
/>
);
}
};
export default Articles
Upvotes: 2