0

So here is my problem. I have an root component that contains navigation and Switch with every component in my page. Navigation is sliding in and out from the left and the way I'm doing this, I'm changing the state in root component, passing prop to and deciding whether or not, should I add class to my nav. The problem is that every component in my app is re-rendering on opening/closing nav. Here is my root component:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      navOpen: false
    }
  }
  toggleNav = () => {
    this.setState({
      navOpen: !this.state.navOpen
    })
  }
  closeNav = (e) => {
    if (this.state.navOpen) {
      this.setState({navOpen: false})
    }
  }

  render() {
    return (
      <main>
        <Header/>
        <Hamburger navOpen={this.state.navOpen} toggleNav={this.toggleNav}/>
        <Navigation navOpen={this.state.navOpen} toggleNav={this.toggleNav}/>
        <section className="container-fluid content" onClick={this.closeNav}>
          <Switch>
            <Route path="/add-recipe/:groupId?" component={NewRecipe}/>
            <Route path="/recipes/:page?/:sortType?/:size?" component={RecipeList}/>
            <Route path="/recipe/:id" component={Recipe}/>
            <Route path="/sign/" component={SignForm}/>
            <Route path="/user/:id" component={User}/>
          </Switch>
        </section>
      </main>

    );
  }
  componentDidMount() {
    this.props.userActions.getUser(this.props.url);
  }
}

function mapStateToProps(state) {
  return {url: state.url.url, user: state.user.loggedUser}
}

function mapDispatchToProps(dispatch) {
  return {
    userActions: bindActionCreators(userActions, dispatch)
  }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));

Navigation is the only component ( besides hamburger) that cares about his parents state so I have no idea why everything is re-rendering. Does anyone have some ideas?

EDIT:

I've added sCU to my nested components like that:

shouldComponentUpdate(nextProps, nextState) {
    // console.log(this.props)
    // console.log("next")
    // console.log(nextProps)
    if (this.props == nextProps) {
      return false
    }
    return true
  }

But it didn't change anything. When I open the navigation props for routes remain the same but they still rerender. I tried to move "navOpen" state to navigation and open it from root component via "ref" but every time I call its method I get "Cannot read property 'toggleNav' of null"

Kreha6
  • 81
  • 8
  • You may want to check out the shouldComponentUpdate lifecycle method: https://reactjs.org/docs/react-component.html#shouldcomponentupdate – cidicles Nov 28 '17 at 01:47
  • this might help answer your question in detail. https://stackoverflow.com/questions/24718709/reactjs-does-render-get-called-any-time-setstate-is-called – Sreekanth Nov 28 '17 at 07:50
  • Possible duplicate of [ReactJS - Does render get called any time "setState" is called?](https://stackoverflow.com/questions/24718709/reactjs-does-render-get-called-any-time-setstate-is-called) – Sreekanth Nov 28 '17 at 07:51

1 Answers1

-1

You can prevent re-rendering by implementing shouldComponentUpdate on the affected component. Beware though, that rendering does not mean that the DOM is being changed. Rendering in react means that react creates a new copy of its internal node tree and compares it to the DOM to see if and where it needs to update it. So don't worry about re-renders unless your component is expensive to create (i.e. it performs a request to a backend or is heavily animated)

SrThompson
  • 5,568
  • 2
  • 17
  • 25