Search code examples
reactjstypescriptreact-hooksreact-router-dom

How to change parent state from child if I am using Switch Route - React?


I have a certain page with one control panel which is used to change current page content, which displayed using Switch-Route. It looks like this:

<div className="controls">
  some controls here
</div>
<Switch>
  <Route exact path='/main/somepage/1/page1' component={page1} />
  <Route exact path='/main/somepage/2/page2' component={page2} />
</Switch>

And I have state in this page:

const [state, setState] = useState<State>({
  currentPage: 2,
  currentGroup: "page1",
  currentDate: new Date().toISOString().substring(0,10),
  loading: false,
})

What I want to do is to change the property loading in current state from page1.

How can I achieve this?


Solution

  • You should apply a pattern called Lifting State Up wherein the state is promoted to a common ancestor and passed down as props to descendent components that care about it.

    Example: Move the state and any callbacks into the parent component rendering the routes, and pass what you need down the specific routed components.

    const [state, setState] = useState<State>({
      currentPage: 2,
      currentGroup: "page1",
      currentDate: new Date().toISOString().substring(0,10),
      loading: false,
    });
    
    const setLoading = (loading: boolean) => setState(state => ({
      ...state,
      loading,
    }));
    
    ...
    
    <div className="controls">
          
      ... some controls here
      
    </div>
    <Switch>
      <Route
        path="/main/somepage/1/page1"
        render={props => <Page1 {...props} setLoading={setLoading} />}
      />
      <Route path="/main/somepage/2/page2" component={Page2} />
    </Switch>