react-layout-components icon indicating copy to clipboard operation
react-layout-components copied to clipboard

Warnings when using with React-Router

Open Rakk4403 opened this issue 8 years ago • 7 comments

Hello, I'm a freshman in React.

I got this message, but I cannot help avoiding this:

Warning: Unknown props `match`, `location`, `history`, `staticContext` on <div> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop

My app is working even with this warnings, but I don't wanna clean up console msgs.

This is my use case:

import { Router, withRouter } from 'react-router-dom';
import { Box, VBox, Container } from 'react-layout-components';

const RoutedVBox = withRouter(VBox);
...
class MyApp extends React.Component {
  render() {
     return (
       <Router>
          <RoutedVBox> ... </RoutedVBox>
       </Router>
     )
  }
}

I tried to removing props of Router(match, location, history, staticContext) by this function, but It breaks successful works.

const MyBox = props => {
  const { match, location, history, staticContext, ...restProps } = props;
  return (<Box {...restProps} />);
}

I just want to remove warning message in console, is there a way for this? There is no answers in SO. Should I keep going with warnings?

Rakk4403 avatar Dec 20 '17 06:12 Rakk4403

The issue is that <Box> and the other RLC components just pass through props to the underlying <divs>. Using withRouter directly on one of those components doesn't make any sense, because the purpose of withRouter is to expose router variables as props into a child component. A VBox isn't a component with behavior, so it won't be able to use those props at all. Why are you trying to apply withRouter to a VBox ?

markerikson avatar Dec 20 '17 16:12 markerikson

@markerikson OK, maybe I'm using wrong way. I'm making a menubar that's on TopBar which is fixed on screen top. And routing view by clicking menu item. Components structure is:

<Router>
  <VBox>
    <Container> 
      <TopBar/> // 1
    </Container>
    <Box>
      <RoutedLoginContainer>  // 1
        {RoutedMenus}
      </RoutedLoginContainer>
    </Box>
  </VBox>
</Router>

RoutedLoginContainer is a Component that checks login status, which shows other Components only in login state.

The router didn't work without withRouter() at first, so I wrapped Box, VBox, Container with withRouter().(That's why I didn't understand what withRouter() do, but now I can see through your explain). Then, It worked with warnings.

I did understand that Components which need router variables need to be wrapped with withRouter(). So, Now I'm removed all withRouter() from Box-Brothers and I wrapped TopBar, RoutedLoginContainer. Is that rightway? I'm keep trying but it's still working unexpectedly.(Not working)

Rakk4403 avatar Dec 22 '17 06:12 Rakk4403

@Rakk4403 : Yeah, that seems more reasonable.

To recap a bit: you only need to use withRouter() if a component needs access to this.props.history, this.props.location, or this.props.match. A component that is just doing layout probably doesn't need those. See the React-Router docs on withRouter for more details.

markerikson avatar Dec 22 '17 16:12 markerikson

@markerikson Thanks for your answer. I finally gave up to solve this problem, and get the code back with <div> instead of Boxs. I hope somebody find out solution.

Problem

Investigating the problem, there was such a situation:

  • This happens with <Route>
  • props.location is updated when <Link> is triggered
  • props.location of Component is not updated when it was a child of Boxs
  • props.location is updated if in <div>
  • wrapping with withrouter(), setting as a child of <Route> give same result.

It works well except being with <Route>, so that I left react-layout-components in other Components.

Rakk4403 avatar Dec 28 '17 05:12 Rakk4403

@markerikson This problem with react router is because you are using React.PureComponent. Read https://reacttraining.com/react-router/web/guides/dealing-with-update-blocking.

My next question is why you are using a PureComponent when the component is stateless? You should not need to use a component at all. The job of the layout is not to optimise the rerendering of something.

seanchambo avatar Mar 23 '18 05:03 seanchambo

Hi, I am facing exactly the same PureComponent issue.

I would like to do that:

<BrowserRouter>
    <Box>
        <Nav
           docs={this.state.docs}
        />
        <Routes/>
    </Box>
</BrowserRouter>

But the Routes component never gets updated by url change. Is there a reason to use that PureComponent instead of a simple stateless component ?

This issue is blocking be for using your library that looks nice ...

npirotte avatar Aug 01 '18 09:08 npirotte

Feel free to send a PR that goes back to using simple components instead. I also honestly believe we don't need them to be pure here. Could be done on user-side by wrapping the component if required.

robinweser avatar Aug 01 '18 10:08 robinweser