Matt Boyle
Matt Boyle

Reputation: 385

Accessing class variable declared in constructor in other parts of the app (React)

I'm currently learning React-native. I am following a Pluralsight tutorial but unfortunately some of his code is out of date. I have the following code:

import Expo from 'expo';
import React from 'react';
import TaskList from './TaskList';
import {
  Component,
  View,
  Navigator,
  Text
} from 'react-native';

class todo extends React.Component {
  constructor(props,context){
    super(props,context);
    this.state ={
      todos: [
        {
          task: 'Task1',
        },
        {
          task: 'Task 2',
        },
      ]
    }
  }
  onAddStarted(){
    this.nav.push({
      name: 'taskform',
        })

  }

  renderScene(route,nav){
    switch(route.name){
      case 'taskform':
      return (
        <Text>Add form comes here!</Text>
      );
      default:
      return(
        <TaskList onAddStarted={this.onAddStarted}
        todos={this.state.todos}/>
      );

    }
  }
  render() {
    return (
    <Navigator initialRoute={{name: 'Tasklist'}}
                ref={((nav)=> {
                  this.nav=nav;
                })}
                renderScene={this.renderScene}/>
    );
  }

}




Expo.registerRootComponent(todo);

My problem is that the line:

    todos={this.state.todos}/>

if i log this.state it errors and state is undefined. If i copy the content of todos inline the code compiles so I know its some problem with scoping but I guess I fundamentally don't understand how to do it properly. Before I started using Navigator I was able to reference this.state from the constructor absolutely fine.

I would appericiate if someone could help me understand.

Thanks!

Upvotes: 0

Views: 2362

Answers (1)

Mark Williams
Mark Williams

Reputation: 2308

You need to give renderScene context, so that it can access this and then its state. To do this you can amend the following line in the render function:

 renderScene={this.renderScene}

to

 renderScene={this.renderScene.bind(this)}

N.B. As using bind generates a new function this can degrade performance (for instance if you are rendering a lot of items). So a common pattern is to do the binding in the constructor:

this.renderScene = this.renderScene.bind(this);

If you take this approach your render function can stay like it is now.

Upvotes: 2

Related Questions