Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing props to a react component wrapped in withRouter() function

I am using React-Router v4 to navigate in my React app. The following is a component wrapped in the withRouter() function to make it able to change route on click:

const LogoName = withRouter(({history, props}) => (
  <h1
    {...props}
    onClick={() => {history.push('/')}}>
    BandMate
  </h1>
));

As you can see I pass the props to the component, which I need in order to change the class of the component. The problem here is that props is undefined in the <LogoName> component. I need to be able to change the class of this component when I click on another component, like this:

<LogoName className={this.state.searchOpen ? "hidden" : ""} />
<div id="search-container">
  <SearchIcon
    onClick={this.handleClick}
    className={this.state.searchOpen ? "active" : ""} />
  <SearchBar className={this.state.searchOpen ? "active" : ""}/>
</div>

Here is how I handle the click. Basically just setting the state.

constructor(){
  super();
  this.state = {
    searchOpen: false
  }
}

handleClick = () => {
  this.setState( {searchOpen: !this.state.searchOpen} );
}

Is there a way for me to pass props to a component that is wrapped inside the withRouter() function or is there a similar way to create a component which has the ability to navigate with React-Router and still receive props?

Thanks in advance.

like image 982
martin36 Avatar asked Jul 21 '17 18:07

martin36


People also ask

How do you pass props into react component?

There is no way to pass props up to a parent component from a child component. We will revisit this caveat later in this tutorial. It's also important to note that React's props are read only (immutable). As a developer, you should never mutate props but only read them in your components.

How do you wrap a component in react?

To wrap one component into another with React, we add the children prop into the parent component. We create the Wrapper component that accepts the children prop. And we put children in a div. Next, we create the Child component that takes the name prop and renders some text.

Why does withRouter not work?

The error "export 'withRouter' (imported as 'withRouter') was not found in 'react-router-dom'" occurs because the withRouter function has been removed in react router v6. To solve the error, install version 5.2. 0 of react router by running npm install [email protected] .


2 Answers

The problem is that while destructuring, you want to destructure props but you are not passing any prop named props to LogoName component

You can change your argument to

const LogoName = withRouter((props) => (
  <h1
    {...props}
    onClick={() => {props.history.push('/')}}>
    BandMate
  </h1>
));

However you can still destructure the props like @Danny also suggested by using the spread operator syntax like

const LogoName = withRouter(({history, ...props}) => (
  <h1
    {...props}
    onClick={() => {history.push('/')}}>
    BandMate
  </h1>
));
like image 61
Shubham Khatri Avatar answered Oct 15 '22 23:10

Shubham Khatri


You're close, just spread the props in your function signature as well:

const LogoName = withRouter(({ history, ...props }) => (
  <h1
    {...props}
    onClick={() => {history.push('/')}}>
    BandMate
  </h1>
));
like image 42
Danny Delott Avatar answered Oct 15 '22 23:10

Danny Delott