【问题标题】:How to use recompose's toClass HOC to add a ref to a functional component?如何使用 recompose 的 toClass HOC 向功能组件添加 ref?
【发布时间】:2018-03-16 07:28:05
【问题描述】:

我正在尝试向 React Native 中的功能组件添加 ref,以便在 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,
};

【问题讨论】:

    标签: reactjs react-native ref recompose


    【解决方案1】:

    我将粘贴一些我设法解决类似问题的代码,我知道这不完全是您的代码,但它显示了解决方案:

    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 的组合来使其工作,我不需要使用@987654326 @HoC 最后是因为只要您使用来自recompose 的任何其他 HoC,您就已经在使用下面的 React 组件类了 :)

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      如果您需要使用ref,只需使用类组件而不是功能组件。但是,如果由于某些原因需要使用功能组件,则可以使用withHandlers。使用方法请看this SO question的回答。

      【讨论】:

      • 我在使用我的实现之前尝试了这个答案,因为它不起作用。但那时我可能只使用一个类组件。
      猜你喜欢
      • 2018-10-13
      • 2019-12-11
      • 2019-02-27
      • 1970-01-01
      • 2020-01-11
      • 2018-01-22
      • 2017-12-31
      • 2017-11-19
      • 2018-02-02
      相关资源
      最近更新 更多