为了账号安全,请及时绑定邮箱和手机立即绑定

通过 cloneElement reactjs 传递 forwardRef

通过 cloneElement reactjs 传递 forwardRef

MYYA 2021-12-23 16:56:41
const ref = useRef()   React.Children.map(this.props.children, (element) => {   React.cloneElement(element, {      innerRef: node => ref,   }) })这里元素是一个组件像下面这样const newComponent = forwardRef(({children, ...otherprops}, ref){    return (     <div {...otherprops} ref={otherprops.innerRef}>       {children}     </div>    )        })得到ref是null在 forwardRef ...可重现的示例:- https://codesandbox.io/s/forward-ref-cloneelement-1msjp
查看完整描述

1 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

尝试更改innerRef为ref,您添加innerRef属性并期望它在以下时间有效ref:


import React, { useRef } from 'react';


function RefForm(props) {

  const setRefs = useRef(new Map()).current;

  const { children } = props;

  return (

    <div>

      {React.Children.map(children, child => {

        return React.cloneElement(child, {

//         v not innerRef

          ref: node => {

            console.log('imHere');

            return !node

              ? setRefs.delete(child.key)

              : setRefs.set(child.key, node);

          }

        });

      })}

    </div>

  );

}


export default RefForm;

然后,您可以根据需要超出 ref:


const Email = React.forwardRef((props, ref) => {

  console.log('email--', ref);

  ref(); // logs "imHere"

  return (

    <div style={{ marginTop: '30px' }}>

      <label>this is email</label>

      <input name="email" ref={props.innerRef} />

    </div>

  );

});

编辑:

对于类组件需要使用另一个键 thenref。


上面的例子有一个警告:refs 不会被传递。那是因为 ref 不是道具。和 key 一样,React 对它的处理方式也不同。如果向 HOC 添加 ref,则 ref 将引用最外层的容器组件,而不是包装的组件。


// class component

class Name extends Component {

  render() {

    console.log('name--', this.props.innerRef);


    return (

      <div style={{ marginTop: '30px' }}>

        <label>this is name</label>

        <input name="name" ref={this.props.innerRef} />

      </div>

    );

  }

}


// functional component

const Email = props => {

  console.log('email--', props.innerRef);

  return (

    <div style={{ marginTop: '30px' }}>

      <label>this is email</label>

      <input name="email" ref={props.innerRef} />

    </div>

  );

};


// cloneElement

function RefForm(props) {

  const setRefs = useRef(new Map()).current;

  const { children } = props;

  return (

    <div>

      {React.Children.map(children, child => {

        return React.cloneElement(child, {

          innerRef: node => {

            return !node

              ? setRefs.delete(child.key)

              : setRefs.set(child.key, node);

          }

        });

      })}

    </div>

  );

}


查看完整回答
反对 回复 2021-12-23
  • 1 回答
  • 0 关注
  • 252 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信