web-dev-qa-db-ja.com

関数内の状態にアクセスできません

私はアプリケーションに_React Native_を使用していますが、ある時点で、コンポーネント内で毎回_this.state.bar[this.state.foo][SOME_NUMBER]_を入力する必要があることに気付きました。

これは完璧に機能しますが、代わりに関数を呼び出してコードをよりクリーンにしたいと考えています。だから、私はこれを構築しました:

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

ただし、これをExpoクライアントで実行すると、次のエラーが発生します。

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

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

これが私のコード全体です。

_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>
        );
    }
}
_

text()関数をAppクラスの外に配置しようとしましたが、同じエラーが発生しました。

Apprender()の外側に配置すると、_unexpected token_エラーが発生しました。

_this.state_をconstructor(props)内に定義し、text()constructor内に配置すると、_ReferenceError: Can't find variable: text_が得られました

4
Mrigank Pawagi

あなたの問題はスコープです。

txt()関数内でアクセスしようとしているthisは、外部コンポーネントthisではなく、独自のthisを指しています。

これを修正する方法はいくつかあります。ここにいくつかあります:

矢印関数を使用する

txtを矢印関数に変換して、外側のthisを使用できます。

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

関数をバインドして、外側のthisを使用できます。

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


    const txt = _txt.bind(this);

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

外側のthisを指す追加の変数を作成できます

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

他のアプローチ

  • txt関数をrender関数の外に移動して、コンポーネントthisにバインドできます。
  • コンポーネントクラスブロック内でアロー関数を使用できます。これは、コンポーネントのthisにバインドしたように見えます。
  • 状態をパラメータとして関数に渡すことができます

...そしてこの振る舞いを修正する方法は他にもいくつかあると確信しています。コンポーネントのthisまたは他のthisをいつ使用するかを知る必要があるだけです。

8
Sergio Moura

ここにいくつかの問題があります。最初に、コンストラクタでtext関数をクラスにバインドする必要があります。また、text関数をrenderメソッドの外に移動して、クラスメソッドとして追加する必要があります(関数名の前にfunctionはありません)。

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>
    );
  }
}
1
Chase DeAnda