Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React exporting withRouter and withStyles error

I am using react along with redux and material-ui to make a component. I am attempting to write an export statement export default connect()(withRouter(FirstPage))(withStyles(styles)(FirstPage))

However, this doesn't seem to work I get an error that says

TypeError: Cannot set property 'props' of undefined

this.props = props;

This error is referencing one of my node_modules.

Here is my full code:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import {withRouter} from 'react-router-dom'
import { withStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import Button from '@material-ui/core/Button';

const styles = theme =>({
    root: {
        maxWidth: 345,
    },

})
class FirstPage extends Component {
    state = {
        feeling: ''
    }

    //This function will dispatch the users response to index.js
    //The dispatch type here is 'SET_FEELING'
    submitData=(event) => {
        event.preventDefault();
        this.props.dispatch({type: 'SET_FEELING', payload: this.state})
        this.changeLocation();
    }

    //This function will update the local state with the users response
    handleChange= (event) => {
        this.setState({
            feeling: event.target.value
        })
    }

    //This function will change the current url when a button is clicked
    changeLocation= ()=> {
        this.props.history.push('/secondPage')
    }

    render(){
        const { classes } = this.props;

        return(
            <div>
                <Card >
                    <CardContent className={classes.root}>

                        <form>
                        <input onChange={this.handleChange} placeholder='How are you feeling' value={this.state.feeling} />
                        </form>
                    </CardContent>
                    <CardActions>
                        <Button onClick={this.submitData}>Submit</Button>
                    </CardActions>
                </Card>
            </div>
        )
    }
}

//this export connects the component to the reduxStore as well as allowing us to use the history props
export default connect()(withRouter(FirstPage))(withStyles(styles)(FirstPage))
like image 711
tdammon Avatar asked Nov 03 '18 03:11

tdammon


People also ask

Is withRouter deprecated?

The library-provided HOC, withRouter, has been deprecated in React Router v6. If you need to use v6 and are using class-based React components, then you will need to write your own HOC which wraps the v6 use* hooks.

Why we use withRouter in react?

You can get access to the history object's properties and the closest <Route> 's match via the withRouter higher-order component. withRouter will pass updated match , location , and history props to the wrapped component whenever it renders.

Why do we use withRouter?

withRouter is a higher order component that will pass closest route's match , current location , and history props to the wrapped component whenever it renders. simply it connects component to the router. Not all components, especially the shared components, will have the access to such router's props.


1 Answers

I believe the following code should work:

export default withRouter(connect()(withStyles(styles)(FirstPage)))

Instead of

export default connect()(withRouter(FirstPage))(withStyles(styles)(FirstPage))

First of all, connect() returns a function that only accepts an argument. Second, connect() should be wrapped inside withRouter(). This problem is stated in the github docs of React Router.

like image 86
Brian Le Avatar answered Oct 08 '22 12:10

Brian Le