1

I have a dropdown BasketContents component (as per this question), which fades in and out when a button is clicked. I also want it to close when a the route is changed by clicking a Link tag. I.e. if it's already open on the Checkout page, if I then click the Home page link I want it to automatically close without clicking the basket's close button.

My Routes.js is the root of the app:

render() {
    return (
      <Router history={hashHistory}>
        <Route path="/" component={App}>
          <IndexRoute component={Home} />
          <Route path="/home" component={Home} />
          <Route path="/checkout" component={Checkout} />
        </Route>
      </Router>
    );
}

App.js looks in part like this:

render() {
    const childrenWithProps = React.Children.map(
        this.props.children,
        child => {
            return (
                React.cloneElement(child, {
                    basket: this.state.basket
                    }
                )
            )
        }
    );
    return (
        <div className="main">
            <HeaderSection basket={this.state.basket} />
            <div className="content">
                {childrenWithProps}
            </div>
        </div>
    )
}

The Basket.js component contains the button:

constructor() {
    super();
    this.state = { open: false }
    this.handleDropDown = this.handleDropDown.bind(this);
}
handleDropDown() {
    this.setState({ open: !this.state.open })
}
render() {
    return(
        <div className="basket">
        <button className="basketBtn" onClick={this.handleDropDown}>Toggle</button>
        <BasketContents 
          contents={this.props.contents} 
          open={this.state.open} 
        />
        </div>
    )
}

I did try adding onEnter to my routes but understandably that doesn't do much since it doesn't have access to the Basket's open state. I would ideally like to set the open state of Basket.js to false when changing route (i.e. when clicking on a Link component). Is this possible?

Community
  • 1
  • 1
GluePear
  • 7,244
  • 20
  • 67
  • 120

1 Answers1

0

I found a solution that doesn't rely on context. The first thing I did, following the React docs, was to lift my basket state up from the Basket component to the App component. This made it easier to manipulate it from a central location.

Then, following a suggestion here, I listened for changes to the browserHistory in the componentWillMount hook in App:

componentWillMount() {
    browserHistory.listen( () =>  {
        this.setState({ basketOpen: false });
    });
}

The result is that when the page changes the basket closes.

GluePear
  • 7,244
  • 20
  • 67
  • 120
  • Listening to history is a way. Additionally, if someone is using redux(or may be flux as well), best way is to dispatch an action to hide it on listening history. This way, you won't have to deal with state and props of the `App component`(top level component) for hiding the ``() separately. And just the status from the props would help. – master_dodo May 27 '17 at 16:15