Home > Software design >  React/nextjs fetch data on a button click, but the button is in a different component
React/nextjs fetch data on a button click, but the button is in a different component

Time:07-19

I have a function in the that fetches the weather data for current location when button is clicked. I want to get this data from the Location component to the pages/index.tsx where I have another components that displays that data.

This is my component structure:

App
  --Layout
    --Header
      --Location (here i fetch the data on click)
    --Home (state)
      --Display 1
        --SubDisplay 1
      --Display 2 

Do I have to pass the data through all the components to the index page? It would be:

  1. UP from Location to Header
  2. UP from Header to Layout
  3. DOWN from Layout to Index page
  4. DOWN from Index page to another components

Is this the best way to handle this?

CodePudding user response:

Due to React's nature regarding data flow, you can only pass props down from parent component to its children, this is known as one-way data binding or unidirectional data flow. Based on the structure of your components, to achieve what you want to do you would need to use Context API or something like redux to centralize your data in one place (or just lifting the states up). However you can try this "workaround" so you don't need to modify your project's structure:

Since your state is in the index/home page, you could define a function in this component that will receive as parameter the data fetched in Location component and set the state with this data, of course you'd need to pass this function via props to Layout component so it can pass it to Header and Header to Location (prop drilling), example:

const Home = () => {
  const [data, setData] = useState([]);

  const handleData = (data) => {
    setData(data);
  }

  return (
    <Layout handleData={handleData}>
      The rest of your components...
    </Layout>
  )
}

Then like I said, pass that function this way: Layout - Header - Location.

In Location:

const Location = ({ handleData }) => {
  const handleClick = () => {
    // Fetch your data on click event and pass it as parameter to handleData function

    handleData(fetchedData);
  }

  // The rest of your component...
}

Hope this helps you.

CodePudding user response:

Suggested solutions based on more complexity

  1. Redux
  2. React context API
  3. Lifting State Up

Lifting state up (Easier than other) sample code

  1. Define shipping function and weatherData as a state in Layout Component, then send shippingFunction into Header component then Location component as prop
const [weatherData,setWeatherData]=useState();
const shippingFunction = function(data) { setWeatherData(data);}
  1. Location Component

    • Call props.shippingFunction in Layout component when weather data was fetched, then send weather data into props.shippingFunction as parameter. Now you have weather data in Layout component
  2. Layout Component

    • At this moment you have filled weatherData and you can pass it as prop into any component you want

  • Related