React Native - 如何访问Refs?

时间:2022-09-04 10:06:07

I'm trying to access this.refs so I can scroll to the top of a Flat List but it is undefined.

我正在尝试访问this.refs,所以我可以滚动到Flat List的顶部,但它是未定义的。

My render method is this:

我的渲染方法是这样的:

render() {
    return (
      <View style={styles.container}>
        { this.state.loading &&
          <ActivityIndicator />
        }
        { !this.state.loading &&
          <FlatList
            ref='flatList'
            data={this.state.facebookPosts}
            onEndReachedThreshold={0}
            onEndReached={({ distanceFromEnd }) => {
              this._getFacebookPosts(this.state.nextPost);
            }}
            renderItem={({item}) => <FacebookPost
              date={item.created_time}
              message={item.message}
              image={item.attachments.data[0].media.image.src}
              url={item.link}
            />}
          />
      }
      </View>
    )
  }
}

As you can see, I have the ref set as 'flatList'.

如您所见,我将ref设置为'flatList'。

I then have a tab bar that when you click on one of the tabs, it is meant to scroll to the top of the list. (I am trying just for not to console log out the this.refs but getting undefined)

然后我有一个标签栏,当你点击其中一个标签时,它就是滚动到列表的顶部。 (我正在尝试不是为了控制台注销this.refs但是未定义)

static navigationOptions = {
    tabBarLabel: 'News',
    showIcon: true,
    tabBarIcon: ({ tintColor }) => (
      <Image
        source={require('../assets/images/newspaper-icon.png')}
        style={[styles.icon, {tintColor: tintColor}]}
      />
    ),
    tabBarOnPress: (scene, jumpToIndex) => {
      // this.refs.listRef.scrollToOffset({x: 0, y: 0, animated: true})
      console.log(this.refs);
      jumpToIndex(scene.index);
    }
  };

What do I need to do differently to get this.refs to not be undefined inside that onTabBarPress function?

我需要做些什么来使this.refs在onTabBarPress函数中不被定义?

3 个解决方案

#1


1  

In my option, you only can access to refs that are in the same class. You do what you wanna do but using componentDidMount when it mounts you scroll the list

在我的选项中,您只能访问同一类中的引用。您可以执行您想要的操作但在安装时使用componentDidMount滚动列表

#2


0  

It appears that you are trying to access a property on the class instance inside a static property which knows nothing about the instance. Static properties are tied to the class not the class instance and so their this keyword is not a reference to the class instance.

您似乎正在尝试访问静态属性中的类实例上的属性,该属性对实例一无所知。静态属性与类绑定而不是类实例,因此它们的this关键字不是对类实例的引用。

It looks like you are using react-navigation and so you could hack the instance (this) into your static navigationOptions property by doing this in componentDidMount.

看起来您正在使用react-navigation,因此您可以通过在componentDidMount中执行此操作将实例(this)破解到静态navigationOptions属性中。

componentDidMount() {
  this.props.navigation.setParams({ instance: this });
}

And then you can define your navigationOptions as a function like this to get access to your navigation params.

然后,您可以将navigationOptions定义为此类函数,以访问导航参数。

static navigationOptions = ({ navigation }) => ({
  tabBarLabel: 'News',
  showIcon: true,
  tabBarIcon: ({ tintColor }) => (
    <Image
      source={require('../assets/images/newspaper-icon.png')}
      style={[styles.icon, {tintColor: tintColor}]}
    />
  ),
  tabBarOnPress: (scene, jumpToIndex) => {
    navigation.state.params.instance.refs.listRef.scrollToOffset({x: 0, y: 0, animated: true})
    jumpToIndex(scene.index);
  }
});

This may not be the best way, but it is a way to accomplish it.

这可能不是最好的方法,但它是实现它的一种方法。

#3


0  

The problems in your code are

您的代码中的问题是

  1. ref takes a function not a string
  2. ref接受函数而不是字符串
  3. scrollToOffset does not use x, y as parameters. If you want to scroll to a certain index, use scrollToIndex instead.
  4. scrollToOffset不使用x,y作为参数。如果要滚动到某个索引,请改用scrollToIndex。
  5. bind isLoading with refreshing is better than inject your FlatList after loading
  6. 使用刷新绑定isLoading比加载后注入FlatList更好

The code below should work:

以下代码应该有效:

class MyListView extends React.Component {
  _listRef;
  ...

  render() {
    return (
      <View>
          <FlatList
            ref={ref => {this._listRef = ref; }}
            data={this.state.facebookPosts}
            renderItem={({item}) => <FacebookPost
              date={item.created_time}
              message={item.message}
              image={item.attachments.data[0].media.image.src}
              url={item.link}
            />}
            ...
            refreshing={this.state.loading}
          />
      }
      </View>
    )
  }

  scrollToIndex = (idx) => {
    this._listRef.scrollToIndex({ index: idx, animated: true });
  }
}

#1


1  

In my option, you only can access to refs that are in the same class. You do what you wanna do but using componentDidMount when it mounts you scroll the list

在我的选项中,您只能访问同一类中的引用。您可以执行您想要的操作但在安装时使用componentDidMount滚动列表

#2


0  

It appears that you are trying to access a property on the class instance inside a static property which knows nothing about the instance. Static properties are tied to the class not the class instance and so their this keyword is not a reference to the class instance.

您似乎正在尝试访问静态属性中的类实例上的属性,该属性对实例一无所知。静态属性与类绑定而不是类实例,因此它们的this关键字不是对类实例的引用。

It looks like you are using react-navigation and so you could hack the instance (this) into your static navigationOptions property by doing this in componentDidMount.

看起来您正在使用react-navigation,因此您可以通过在componentDidMount中执行此操作将实例(this)破解到静态navigationOptions属性中。

componentDidMount() {
  this.props.navigation.setParams({ instance: this });
}

And then you can define your navigationOptions as a function like this to get access to your navigation params.

然后,您可以将navigationOptions定义为此类函数,以访问导航参数。

static navigationOptions = ({ navigation }) => ({
  tabBarLabel: 'News',
  showIcon: true,
  tabBarIcon: ({ tintColor }) => (
    <Image
      source={require('../assets/images/newspaper-icon.png')}
      style={[styles.icon, {tintColor: tintColor}]}
    />
  ),
  tabBarOnPress: (scene, jumpToIndex) => {
    navigation.state.params.instance.refs.listRef.scrollToOffset({x: 0, y: 0, animated: true})
    jumpToIndex(scene.index);
  }
});

This may not be the best way, but it is a way to accomplish it.

这可能不是最好的方法,但它是实现它的一种方法。

#3


0  

The problems in your code are

您的代码中的问题是

  1. ref takes a function not a string
  2. ref接受函数而不是字符串
  3. scrollToOffset does not use x, y as parameters. If you want to scroll to a certain index, use scrollToIndex instead.
  4. scrollToOffset不使用x,y作为参数。如果要滚动到某个索引,请改用scrollToIndex。
  5. bind isLoading with refreshing is better than inject your FlatList after loading
  6. 使用刷新绑定isLoading比加载后注入FlatList更好

The code below should work:

以下代码应该有效:

class MyListView extends React.Component {
  _listRef;
  ...

  render() {
    return (
      <View>
          <FlatList
            ref={ref => {this._listRef = ref; }}
            data={this.state.facebookPosts}
            renderItem={({item}) => <FacebookPost
              date={item.created_time}
              message={item.message}
              image={item.attachments.data[0].media.image.src}
              url={item.link}
            />}
            ...
            refreshing={this.state.loading}
          />
      }
      </View>
    )
  }

  scrollToIndex = (idx) => {
    this._listRef.scrollToIndex({ index: idx, animated: true });
  }
}