【问题标题】:Undefined is not an object evaluating this.state/this.propsUndefined 不是评估 this.state/this.props 的对象
【发布时间】:2017-04-08 01:10:43
【问题描述】:

如何在 React Native 中绑定超出范围的函数?我收到了错误:

undefined is not an object evaluating this.state   

&

undefined is not an object evaluating this.props

我正在使用渲染方法在数据加载后调用renderGPSDataFromServer()。问题是,我试图在renderGPSDataFromServer() 中使用_buttonPress()calcRow(),但我遇到了这些错误。

我已经添加了

constructor(props) {
    super(props);
    this._buttonPress = this._buttonPress.bind(this);
    this.calcRow = this.calcRow.bind(this);

到我的构造函数,我已将_buttonPress() { 更改为_buttonPress = () => {,但仍然没有。

我想我理解了这个问题,但我不知道如何解决它:

renderLoadingView() {
    return (
        <View style={[styles.cardContainer, styles.loading]}>
            <Text style={styles.restData}>
                Loading ...
            </Text>
        </View>
    )
}

_buttonPress = () =>  {
    this.props.navigator.push({
        id: 'Main'
    })
}

renderGPSDataFromServer =() => {
    const {loaded} = this.state;
    const {state} = this.state;

    return this.state.dataArr.map(function(data, i){
        return(
            <View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
                <View style={styles.cardContentLeft}>
                    <TouchableHighlight style={styles.button}
                        onPress={this._buttonPress().bind(this)}>
                        <Text style={styles.restData}>View Video</Text>
                    </TouchableHighlight>
                </View>

          <View style={styles.cardContentRight}>
            <Text style={styles.restData}>{i}</Text>
            <View style={styles.gpsDataContainer}>
              <Text style={styles.gpsData}>
              {Number(data.lat).toFixed(2)}</Text>
              <Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
            </View>
            <Text  style={styles.gpsData}>
            {this.calcRow(55,55).bind(this)}
            </Text>
          </View>
        </View>
      );
    });
}

render = ()=> {
    if (!this.state.loaded) {
      return this.renderLoadingView();
    }
    return(
      <View>
        {this.renderGPSDataFromServer()}
      </View>
    )
}};

我该如何解决这个问题?在这种情况下,问题是什么?

【问题讨论】:

    标签: javascript reactjs scope react-native jsx


    【解决方案1】:

    this.props 是只读的

    React docs - component and props

    因此组件不应该尝试修改它们,更不用说像你在这里所做的那样改变它们:

      _buttonPress = () =>  {
          this.props.navigator.push({
            id: 'Main'
          })
      }
    

    我建议改用 state:

    _buttonPress = () =>  {
      this.setState = {
        ...this.state,
        navigator: {
          ...this.state.navigator,
          id: 'Main'
        }
      }
    }
    

    关于您的绑定问题:

    .map 方法采用第二个参数,用于在调用回调时设置 this 的值。

    在您的问题的上下文中,您只需将 this 作为第二个参数传递给您的 .map 方法即可将组件范围的 this 绑定到它。

    【讨论】:

      【解决方案2】:

      发生这种情况是因为map 方法中的函数创建了不同的上下文。您可以使用箭头函数作为 map 方法中的回调来进行词法绑定。这应该可以解决您遇到的问题。

      renderGPSDataFromServer =() => {
      
          const {loaded} = this.state;
          const {state} = this.state;
      
          return this.state.dataArr.map((data, i) => {
            return(
              <View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
      
                <View style={styles.cardContentLeft}>
                  <TouchableHighlight style={styles.button}
                   onPress={this._buttonPress().bind(this)}>
                  <Text style={styles.restData}>View Video</Text>
                  </TouchableHighlight>
                </View>
      
                <View style={styles.cardContentRight}>
                  <Text style={styles.restData}>{i}</Text>
                  <View style={styles.gpsDataContainer}>
                    <Text style={styles.gpsData}>
                    {Number(data.lat).toFixed(2)}</Text>
                    <Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
                  </View>
                  <Text  style={styles.gpsData}>
                  {this.calcRow(55,55).bind(this)}
                  </Text>
                </View>
      
              </View>
            );
          });
        }

      此外,一旦您在类函数定义中使用了箭头函数,您 不需要在构造函数中绑定它们:

      constructor(props) {
        super(props);
        this._customMethodDefinedUsingFatArrow = this._customMethodDefinedUsingFatArrow.bind(this)
      }

      此外,一旦你将类函数定义为箭头函数,你 调用它们时也不需要使用箭头函数:

      class Example extends React.Component {
        myfunc = () => {
          this.nextFunc()
        }
      
        nextFunc = () => {
          console.log('hello hello')
        }
      
        render() {
          // this will give you the desired result
          return (
            <TouchableOpacity onPress={this.myFunc} />
          )
          
          // you don't need to do this
          return (
            <TouchableOpacity onPress={() => this.myFunc()} />
          )
        }
      }

      【讨论】:

        【解决方案3】:

        不确定这是否是问题所在,但我认为是代码错误,可能会导致您的问题。

        <View style={styles.cardContentLeft}>
          <TouchableHighlight style={styles.button}
           onPress={this._buttonPress().bind(this)}>
          <Text style={styles.restData}>View Video</Text>
          </TouchableHighlight>
        </View>
        

        特别是这一行onPress={this._buttonPress().bind(this)}&gt; 您正在调用该函数并同时绑定它。

        这样做的正确方法是这样

        onPress={this._buttonPress.bind(this)}>
        

        这样该函数将仅在 onPress 上被调用。

        【讨论】:

          【解决方案4】:

          您正朝着正确的方向前进,但仍有一个小问题。您正在将function 传递给您的map 回调,该回调与您的组件具有不同的范围(this)(因为它不是箭头函数),所以当您执行bind(this) 时,您将回调重新绑定到使用map 的范围。我认为这应该可行,它基本上将您传递给map 的回调转换为箭头函数。另外,由于你bind你的函数在构造函数中,你不需要再做一次:

            // The constructor logic remains the same
            // ....
            renderLoadingView() {
                return (
                <View style={[styles.cardContainer, styles.loading]}>
                  <Text style={styles.restData}>
                    Loading ...
                  </Text>
                </View>
                )
              }
          
            _buttonPress = () =>  {
                this.props.navigator.push({
                  id: 'Main'
                })
            }
          
            renderGPSDataFromServer =() => {
          
              const {loaded} = this.state;
              const {state} = this.state;
          
              return this.state.dataArr.map((data, i) => {
                return(
                  <View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
          
                    <View style={styles.cardContentLeft}>
                      <TouchableHighlight style={styles.button}
                       onPress={this._buttonPress}>
                      <Text style={styles.restData}>View Video</Text>
                      </TouchableHighlight>
                    </View>
          
                    <View style={styles.cardContentRight}>
                      <Text style={styles.restData}>{i}</Text>
                      <View style={styles.gpsDataContainer}>
                        <Text style={styles.gpsData}>
                        {Number(data.lat).toFixed(2)}</Text>
                        <Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
                      </View>
                      <Text  style={styles.gpsData}>
                      {this.calcRow(55,55).bind(this)}
                      </Text>
                    </View>
          
                  </View>
                );
              });
            }
          
            render = ()=> {
              if (!this.state.loaded) {
                return this.renderLoadingView();
              }
              return(
                <View>
                  {this.renderGPSDataFromServer()}
                </View>
              )
            }};
          

          【讨论】:

          • 我也认为你应该听从 Pineda 关于如何处理道具的建议,我在回答中完全忽略了这一点。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-08-24
          • 2015-07-16
          • 2020-07-16
          • 2018-08-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多