Home > other >  How to use return a parent and child component separately in React?
How to use return a parent and child component separately in React?

Time:03-29

I have a GetData component where I make an API call. I then pass the data forward as props to the graph components that will use the data. In the app I then return the GetData component to render the graphs. The issue is that both graphs are now merged into one component. I want to separate them so I can give both components their own box and put a button box next to each.

Is there a way to approach these components separately to give both graphs separate containers and place button components next to them?

This is my code:

GetData:

import React, { useState, useEffect, Fragment } from "react";
import axios from "axios";
import GraphChart from "../components/GraphChart";
import BarChart from "../components/BarChart";

const config = {
  "Content-Type": "application/json",
  Accept: "application/json",
};

const GetData = () => {
  const [arrayFlow, setArrayFlow] = useState([]);

  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(async () => {
    const { data } = await axios({
      url: "http://192.168.170./*",
      method: "GET",
      data: null,
      withCredentials: true,
      headers: config,
    });
    console.log(data);

    const newData = data.value.map((d) => {
      const idNumber = d._idNumber;
      const startDate =
        d.startDate;
      const endDate =
        d._endDate;
      return {
        idNumber,
        startDate,
        endDate,
      };
    });
    setArrayFlow(newData);
  }, []);

  return (
    <>
      <GraphChart flow={arrayFlow} />
      <BarChart flow={arrayFlow} />
    </>
  );
};
export default GetData;

App.js:

import "./App.css";
import React from "react";
import GetData from './apiData/GetData'
import { Button } from "./components/button/Button";
import GraphChart from "./components/GraphChart";

const App = () => {
  
  return (
    <div className="app">
      <div className="example">
        <div className="graph-box">
          <div id="wrapper">
            <GraphChart />
          </div>
          <div className="side-bar">
            <Button>Sort</Button>
          </div>
        </div>
        <div className="graph-box">
          <div id="wrapper">
            <GetData />
          </div>
          <div className="side-bar">
            <Button>Sort</Button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default App;

Chart, removed clutter:

import React, { useEffect, useState } from "react";
import Chart from "react-apexcharts";
import _ from "lodash";
import { format, parseISO } from "date-fns";

const GraphChart = ({ instroom }) => {
  const [category, setCategory] = useState([]);
  const [data, setData] = useState([]);

  useEffect(() => {
    let series = [];
    let categories = [];
    let orderedFlow = _.orderBy(
      flow,
      ["startDate"],
      ["asc", "desc"]
    );
    for (let i = 0; i < orderedFlow.length; i  ) {
      series.push(orderedFlow[i].idNumber);
      categories = categories.concat(
        format(
          parseISO(orderedFlow[i].startDate),
          "dd MMM YYY"
        )
      );
    }
    setCategory(categories);
    setData(series);
  }, [flow]);

 return (
    <div>
      <Chart
        options={{
          chart: {
            id: "basic-graph",
            }}}
        series={[
          {
            name: "ID",
            data: data,
          },
        ]}
        type="area"
        width="1500"
        height="500"
      />
    </div>
  );
};

export default GraphChart;

CodePudding user response:

What are you exactly asking for? You have App.js file, inside it you are having 2 components with a SORT button each. One is GraphChart and second is GetData, Inside GetData component you are again returning 2 components i.e. GraphChart and BarChart. So, what are you asking here exactly?

PS -> I am not allowed to comment, so that's why I am asking here.

CodePudding user response:

Why don't you create a useGetData hook, instead of using the <GetData/> component?

That hook will be responsible for fetching the data. You can call it from the parent of both of your <Graphs/> and provide the data to both of them.

The useGetData code would look something like this:

useGetData.js

const useGetData = () => { // You can also pass some params to it
  const [data,setData] = useState(null);
  const [isLoading,setIsLoading] = useState(true);
  const [error,setError] = useState(null);

  useEffect(() => {
    // CALL AXIOS
    
    // ON SUCCESS
    // setData(data) and setIsLoading(false)

    // ON ERROR
    // setError(error) and setIsLoading(false)
  },[]);

  return {
    data,
    isLoading,
    error
  };

};

App.js

const { data, isLoading, error } = useGetdata();

return (
  isLoading ? <Spinner/>
  : error ? <Error/>
  : <Chart1 data={data}/> and <Chart2 data={data}/>
);
  • Related