繁体   English   中英

如何使用 recompose 的 toClass HOC 将 ref 添加到功能组件?

[英]How to use recompose's toClass HOC to add a ref to a functional component?

我正在尝试向 React Native 中的功能组件添加一个引用,以便在 FlatList 组件上使用 scrollToEnd。

我想为此使用 recompose,正如他们的文档所述, toClass() 应该能够处理这个问题。 但是,没有给出示例。

目前,这是我失败的实现。 有人能告诉我我做错了什么吗?

我将不胜感激!

import React from 'react';
import PropTypes from 'prop-types';
import { FlatList, View, Text } from 'react-native';
import { graphql } from 'react-apollo';
import { compose, toClass, lifecycle } from 'recompose';

import CommentItem from './CommentItem';
import { commentsQuery } from '../../queries/comments';

const CommentScreen = ({ onRef, currentUser, data: { comments, loading } }) => {
  if (loading) {
    return (
      <View>
        <Text>Loading...</Text>
      </View>
    );
  }

  return (
    <FlatList
      ref={ref => {
        this.refs.commentList = ref;
      }}
      data={comments}
      keyExtractor={item => item.id}
      renderItem={({ item }) => <CommentItem {...item} currentUser={currentUser} />}
    />
  );
};

export default compose(
  toClass,
  graphql(commentsQuery),
  lifecycle({
    componentDidMount() {
      console.log('PROPZZZ', this.commentList);
    },
  }),
)(CommentScreen);

CommentScreen.propTypes = {
  fetchComments: PropTypes.func.isRequired,
  updateId: PropTypes.number.isRequired,
  comments: PropTypes.arrayOf(Object),
  text: PropTypes.string.isRequired,
};

如果需要使用ref只需使用类组件而不是功能组件。 但是,如果由于某些原因需要使用功能组件,则可以使用withHandlers 请查看此SO问题的答案,了解如何使用它。

您必须从生命周期方法中的this.refs访问您的元素。

lifecycle({
  componentDidMount() {
    console.log('PROPZZZ', this.refs.commentList);
    //                          ^^^^
  }
})

你可以在这里看到它: https//snack.expo.io/Sy-rCBQhW

我要粘贴一些我设法使用类似问题的代码,我知道它不是你的代码,但它显示了解决方案:

import React from 'react'
import { compose, withState, withHandlers, lifecycle } from 'recompose'

import Left from './Left'
import Right from './Right'
import Modals from './Modals'
import { ActionBar, Container } from './styles'

let ref = null

const enhance = compose(
  withState('position', 'setPos', 'relative'),
  withHandlers({
    isTop: ({ setPos }) => () => {
      const { top } = ref && ref.getBoundingClientRect()
      top && setPos(top <= 0 ? 'fixed' : 'relative')
    },
  }),
  lifecycle({
    componentDidMount() {
      window.addEventListener('scroll', this.props.isTop)
    },
    componentWillUnmount() {
      window.removeEventListener('scroll', this.props.isTop)
    },
  })
)

export default enhance(({ position, ...props }) => (
  <Container innerRef={el => (ref = el)}>
    <ActionBar position={position}>
      <Left {...props} />
      <Right {...props} />
      <Modals {...props} />
    </ActionBar>
  </Container>
))

你可以看到这里的关键是将ref存储在一个变量中并使用withState + withHandlers + lifecycle的混合来使它工作,我最后不需要使用toClass HoC,因为只要你使用任何其他HoCrecompose你已经在下面使用React组件类:)

希望能帮助到你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM