使用 react-redux (v. 6.0.1) 在功能组件中转发 ref

IT技术 reactjs react-redux
2021-04-27 14:05:28

我正在尝试forwardRef在我的功能组件中使用,该组件也使用react-redux. 我的组件如下所示:

const InfiniteTable = ({
  columns,
  url,
  data,
  stateKey,
  loading,
  loadMore,
  fetchData,
  customRecordParams,
  ...rest
}, ref) => {
  const [start, setStart] = useState(0);
  const tableRef = React.createRef();

  console.log(rest);

  let dataSource = data;
  if (customRecordParams) dataSource = _.map(dataSource, customRecordParams);
  if (dataSource.length > FETCH_LIMIT)
    dataSource = _.slice(dataSource, 0, start + FETCH_LIMIT);

  useEffect(() => setupScroll(setStart, tableRef), []);
  useEffect(() => {
    if (loadMore) fetchData(url, stateKey, { start });
  }, [start, loadMore]);

  useImperativeHandle(ref, () => ({
    handleSearch: term => console.log(term),
    handleReset: () => console.log("reset")
  }));

  return (
    <Table
      columns={columns}
      dataSource={dataSource}
      pagination={false}
      showHeader
      loading={loading}
    />
  );
}; 

const mapStateToProps = (state, ownProps) => ({
  data: Object.values(state[ownProps.stateKey].data),
  loading: state[ownProps.stateKey].isFetching,
  loadMore: state[ownProps.stateKey].loadMore
});

export default connect(
  mapStateToProps,
  { fetchData },
  null,
  { forwardRef: true }
)(InfiniteTable);

但是,当我尝试使用带有 ref 属性的组件时出现此错误:

警告:不能为函数组件提供引用。尝试访问此引用将失败。你的意思是使用 React.forwardRef() 吗?

我究竟做错了什么?

1个回答

InfiniteTable签名不正确,它是作为功能组件中的第二个参数接收inheritancecontext,而不是ref. 为了接收 ref 对象以与 一起使用useImperativeHandle,组件应该用 包裹React.forwardRef

正如参考文献所述,

useImperativeHandle 自定义在使用 ref 时暴露给父组件的实例值。与往常一样,在大多数情况下应该避免使用 refs 的命令式代码。useImperativeHandle 应该与 forwardRef 一起使用

它应该是:

const InfiniteTable = forwardRef((props, ref) => { ... });

export default connect(
  mapStateToProps,
  { fetchData },
  null,
  { forwardRef: true }
)(InfiniteTable);