Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access State inside Function

I am using React Native for my application, and at one point, I noticed that I have to type this.state.bar[this.state.foo][SOME_NUMBER] every time, within my components.

This works perfectly fine, but I want to make my code cleaner by calling a function instead. So, I constructed this:

function txt(n){
    return this.state.bar[this.state.foo][n];
}

However, when I run this in the Expo client, I get the following error:

TypeError: undefined is not an object (evaluating 'this.state.bar')

This error is located at:
    in App...
    ....

Here is my entire code.

import React, 
    { Component } 
from 'react';
import { 
     ... 
} from 'react-native';

export default class App extends React.Component {
    state = {
        foo: 'ABC',
        bar: {
            'ABC': [
                '...',
                '...',
                '...'
            ]
        }
    };
    render() {
        function txt(n){
            return this.state.bar[this.state.foo][n];
        }
        return (
            <View>
                ...  
            </View>
        );
    }
}

I tried placing the text() function outside the App class, but got the same error.

When I placed it outside render() in App, I got an unexpected token error.

When I defined this.state within a constructor(props) and placed text() within the constructor, I got ReferenceError: Can't find variable: text

like image 223
Mrigank Pawagi Avatar asked Oct 19 '18 14:10

Mrigank Pawagi


People also ask

How do you access a state inside a function?

In order to access the current state in this case, we will need to create the closure around an object. The reference to the object will always be the same in the closure function but the actual value stored by the object will be changed each time the Counter function runs.

Can't access state inside function React function component?

This is happening because the getProducts is using the value products had when getProducts was being declared, not the one products has when the getProducts function is called. This is always the case when you want to access the most recent state directly in non-inline functions.

Can I use state inside functional component?

React components can possess internal “state,” a set of key-value pairs which belong to the component. When the state changes, React re-renders the component. Historically, state could only be used in class components. Using hooks, you can apply state to functional components too.

How can you access the state of a component?

In React we can access the child's state using Refs. we will assign a Refs for the child component in the parent component. then using Refs we can access the child's state.


2 Answers

Your problem is scoping.

The this that you're trying to access inside the txt() function is pointing to its own this, and not the outer component this.

There are several ways to fix this. here's a few:

Use arrow functions

You can transform txt into an arrow function to use the outer this:

render() {
    const txt = (n) => {
        return this.state.bar[this.state.foo][n];
    }
    return (
        <View>
            ...  
        </View>
    );
}

You can bind the function to use the outer this

render() {
    function _txt(n){
        return this.state.bar[this.state.foo][n];
    }


    const txt = _txt.bind(this);

    return (
        <View>
            ...  
        </View>
    );
}

You can create an additional variable that points to the outer this

render() {
    const self = this;
    function txt(n){
        return self.state.bar[self.state.foo][n];
    }
    return (
        <View>
            ...  
        </View>
    );
}

Other approaches

  • You can move the txt function to outside of the render function and bind it to the component this.
  • You can use an arrow function inside the component class block, which will seem like you've bound it to the component's this.
  • You can pass the state as a parameter to the function

...and I'm sure that there are several other ways to fix this behaviour. You just need to know when you're using the component's this or some other this.

like image 132
Sergio Moura Avatar answered Sep 19 '22 21:09

Sergio Moura


A few issues here. First, you need to bind the text function to the class in the constructor. You also need to move the text function out of the render method and add it as a class method (no function in front of function name):

import React,
{ Component }
  from 'react';
import {
...
} from 'react-native';

export default class App extends React.Component {

  constructor () {
    super();
    this.state = {
      foo: 'ABC',
      bar: {
        'ABC': [
          '...',
          '...',
          '...'
        ]
      }
    };
    this.text = this.text.bind(this);
  }

  text (n) {
    return this.state.bar[this.state.foo][n];
  }

  render() {
    return (
      <View>
        ...
      </View>
    );
  }
}
like image 33
Chase DeAnda Avatar answered Sep 17 '22 21:09

Chase DeAnda