父组件循环遍历创建多个子组件,但是想要命令式控制子组件(forwardRef + useImperativeHandle),那么是需要在父组件创建多个ref进行传输吗?

父组件循环遍历创建多个子组件,但是想要命令式控制子组件(forwardRef + useImperativeHandle),那么是需要在父组件创建多个ref进行传输吗?

父组件创建了多个子组件:

...
<div>
  {
    props.data.map((item, index) => (
      <div  key={index}>
        <SubContainer {...item}  /* 这里需要每个子组件都传递ref吗 ref={ctlChildRef} */ >
        </SubContainer>
      </div>
    ))
  }
</div>

1、是否必须给每个子组件传入ref是吗?

2、如果是,是如何在父组件循环创建多个ref呢?因为ref的名称不能用循环的index组合,这里应该如何做的呢?


更新-1

我的需求是:

我有一个组件,UI图如下:

给定props然后遍历data创建多个子组件(白色背景的就是一个子组件)

QQ_1723778584099.png

然后,我需要在父组件(整个大的淡蓝色背景的组件)进行命令式控制子组件内的操作。

比如我父组件点击一个按钮(这里传输子组件的id,和子组件内的item内的id)那么就相应地focus(变颜色)。

阅读 1.5k
3 个回答
新手上路,请多包涵

这或许不是最好的解决方法,能描述一下你的需求吗?

需要遍历获取 Ref,可参考:

import React, { forwardRef, useImperativeHandle, useMemo } from 'react';

interface ChildProps {
  name: string;
}
interface ChildRef {
  active(): void;
}

const Child = forwardRef<ChildRef, ChildProps>((props, ref) => {
  const { name } = props;

  useImperativeHandle(
    ref,
    () => ({
      active() {},
    }),
    []
  );

  return <div>{name}</div>;
});

export function Demo() {
  const data = [
    {
      id: '1',
      name: 'child1',
    },
    {
      id: '2',
      name: 'child2',
    },
  ];
  const childRefs = useMemo<Map<string, ChildRef>>(() => new Map(), []);

  const registerRef = (id: string, r: ChildRef) => {
    childRefs.set(id, r);
    return () => {
      childRefs.delete(id);
    };
  };

  const handleActive = () => {
    childRefs.get('1')?.active();
  };

  return (
    <div>
      <button onClick={handleActive}>激活 child1</button>
      {data.map((item) => (
        <Child
          key={item.id}
          name={item.name}
          ref={(r: ChildRef) => registerRef(item.id, r)}
        />
      ))}
    </div>
  );
}
新手上路,请多包涵
推荐问题
logo
Microsoft
子站问答
访问
宣传栏