Erwin
Erwin

Reputation: 3

Data are not rendering in react component

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

Answers (3)

Ram Sankhavaram
Ram Sankhavaram

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

Andreq Frenkel
Andreq Frenkel

Reputation: 1208

You have to separate loading logic and render. In your case you are using Component function, you should

  1. Create state for your data with useState(null), where null is initial state

  2. 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

Gilad Bar
Gilad Bar

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

Related Questions