user10398929
user10398929

Reputation:

react redirect issue I'm getting cannot read setState of undefined

I'm trying to redirect to the second page on button click. Yet, Im getting cannot read setState of undefined when working the code below.

  this.state = {
  arr: [],
  redirect: false
};
setRedirect() {
   this.setState({
  redirect : true
})
}


renderRedirect(){
  if (this.state.redirect) {
  return <Redirect to='/target' />
 }
}

render() {
return (
    <div>
    {this.renderRedirect()}
    <button onClick={this.setRedirect}>Redirect</button>
   </div>
)}

Upvotes: 0

Views: 70

Answers (4)

Naveen Vignesh
Naveen Vignesh

Reputation: 1357

Add setState inside constructor or define as class property

constructor(props) {
  super(props);
  this.state = {
    arr: [],
    redirect: false
  }
}

Or

class abc extends Component {
  state = {
    arr: [],
    redirect: false,
  }
}

Also

Change function to es6 or use bind

ES6 Solution

setRedirect = () => {
   // Code block
}

Upvotes: 1

Hemadri Dasari
Hemadri Dasari

Reputation: 34004

You need to move state inside constructor and bind setRedirect in constructor only.

Few Other answers suggested to bind it directly in render don’t do that. Bind it always in constructor

To fix the issue primarily you need to bind setRedirect function

  constructor(props){
        super(props);
        this.state = {
             arr: [],
             redirect: false
         };
         this.setRedirect = this.setRedirect.bind(this);
     }

Also Change

    <button onClick={this.setRedirect}>Redirect</button>

To

    <button onClick={() => this.setRedirect()}>Redirect</button>

Otherwise setRedirect gets called on render so to prevent that use () =>

Upvotes: 0

Thakur Karthik
Thakur Karthik

Reputation: 3538

You need to bind the setDirect function like this

class App extends React.Component {
 state = {
  arr: [],
  redirect: false
 };
 setRedirect() {
  this.setState({
   redirect: true
  })
 }


 renderRedirect(){
  if (this.state.redirect) {
   return <Redirect to='/target'/>
  }
 }

 render() {
  return (
   <div>
    {this.renderRedirect()}
    <button onClick={this.setRedirect.bind(this)}>Redirect</button> //binding here is important
   </div>
  )
 }
}

or you have to use the constructor of class

constructor(props) {
 super(props);
 this.state = {
  arr: [],
  redirect: false
 }
}

Upvotes: 0

Revansiddh
Revansiddh

Reputation: 3062

Constructor

this.state = {
  arr: [],
  redirect: false
}

function that toggle redirect flag outside constructor

setRedirect=()=>{
  this.setState({redirect:true})
}

finally you render method

render() {
   return (
     <div>
      {this.renderRedirect()}
      <button onClick={this.setRedirect}>Redirect</button>
     </div>
  )
}

I think here is issue of binding this if you haven't written setState in constructor. If so then there are threee ways of changes this so that you setRedirect can have access to this of whole class. (so that it can access state).

  1. binding in render like onClick={()=>this.setRedirect.bind(this)}
  2. binding in constructor like

    this.setRedirect = this.setRedirect.bind(this)

  3. last on considering performance the above menthod setRedirect =()=>{}

Because 1,2 creates new function at every render.

Upvotes: 0

Related Questions