NextJS: data fetching in child component and pass to parent component

Viewed 7518

I am new to Next.js and trying to make an e-commerce project. I am stuck on if a child component Sort Component has a post request to the server to filter the data and pass it back to the Products component as product props.

The folder structure is like this:

<>
 <Sort />
 <Products products={products} />
</>

Inside the Sort component, I will send the filter parameters back to the server. So the method I am thinking of is using Redux, but can I use the useSWR hook? As the action is taken at Sort component, seems useSWR hook need to have the action and the data returned together in the same component, is that correct?

3 Answers

Your code is looks like that:

<>
 <Sort />
 <Products products={products} />
</>

In this case you have to create a shared state in the container of that two, like this:

1, You can use a simple shared state, like:

function ContainerOfTwo(props) {
  const [sharedState, setSharedState] = React.useState({});
  return (
    <>
      <Sort setSharedState={setSharedState} sharedState={sharedState} />
      <Products products={products} setSharedState={setSharedState} sharedState={sharedState} />
    </>
  )
}

2, Use the native React contextAPI maybe with useReducer. (This is a smaller and more specific state management. Small resource)

3, Use Redux. (For larger, and more robostus state handler)

Summary: I would go with shared state for the first, if thats not enought with your requirements, go with the contextAPI or with redux depending on your needs. If you doing good, should not be a large issue to hold the state to contextAPI/redux.

The simplest solution, although perhaps not the best in the long term depending upon how complex the interactions between these child components can get, is managing the state and passing state and hooks to set the state to these children.

function ParentComponent(props) {
  const initialState = {};
  const [ sortedData, setSortedData ] = React.useState(initialState);

  return(
    <>
      <Sort setSortedData={setSortedData} />
      <Products sortedData={sortedData} />
    </>
  )
}

Note: Since the Products component is dependent upon the sortedData to be updated you may want to set conditions on its render as you await the async fetch in Sort.

Again, if there will be any degree of complexity beyond this then you may want to use Redux or React's ContextAPI to manage the state. For example, if sortedData is used in any child components of Sort or Products then you'd want to manage using Redux or ContextAPI so you're not passing it along child to child.

You can read more about the useContext hook here: useContext

You can use callback method from parent to child and setting the state value in the parent and passing this value to other child components.

class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            products: []
        };
    }
    callBackMethod = (products) => {
        this.setState({products})
    }
    render() {
        const { products } = this.state;
        return (
            <>
                <Sort callBackMethod={this.callBackMethod}/>
                <Products products={products} />
            </>
        );
    }
}

export default Parent;
Related