React - 如何将 `ref` 从子组件传递到父组件?

24

我有一个父组件和一个子组件,我想在父组件中访问子组件中的一个元素的ref。我能通过props传递吗?

我有一个父组件和一个子组件,我想要访问子组件中的一个元素的ref,并且在父组件中使用。我可以通过props来传递吗?

// Child Component (Dumb):
export default props =>
    <input type='number' ref='element' />

// Parent Component (Smart):
class Parent extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        const node = this.refs.element; // undefined
    }

    render() {
        return <Dumb { ...this.props }/>
    }
}

1
尝试这个 https://dev59.com/277pa4cB1Zd3GeqPrxw7#68934050 - bhaRATh
5个回答

44
你可以使用回调函数语法来获取引用
// Dumb:
export default props =>
    <input type='number' ref={props.setRef} />

// Smart:
class Parent extends Component {
    constructor(props) {
        super(props);
    }

    setRef(ref) {
        this.inputRef = ref;
    }

    render(){
        return <Dumb {...this.props} setRef={this.setRef} />
    }
}

我更喜欢使用回调函数而不是将ref传递给子组件,因为这样你可以保持对父组件的引用。对于简单的组件来说这没有问题,但对于大型/复杂的组件,按照最佳实践应该使用回调函数。 - Khalid Azam
@Timo在Dumb组件中是否也有引用ref的方法? - Anil Namde
@timo 在 Dumb 组件中使用 ref,这只适用于 DOM 元素。Dumb 组件没有实例,因此它将 DOM 发送到父组件。 - elporfirio
1
如何在 Dumb 组件内给 <input> 添加 onChange() 事件并且在父组件中的 onChange 函数定义中获取 ref - Hareesh

13

如果你使用React ^16.0.0,你可以使用React.createRef()。根据@Timo的答案,代码如下:

// Dumb:
export default props =>
    <input type='number' ref={props.setRef} />

// Smart:
class Parent extends Component {
    constructor(props) {
        super(props);
        this.ref1 = React.createRef()
    }

    render(){
        return <Dumb {...this.props} setRef={this.ref1} />
    }
}

3
根据 文档

你不能在函数式组件上使用 ref 属性,因为它们没有实例。如果需要引用该组件,就像需要生命周期方法或状态一样,应将其转换为类。

所以我认为,如果您想要使用 ref,则需要使用 class
请查看:https://github.com/facebook/react/issues/4936

5
由于React Hooks 的引入,特别是 useRef hook,这种情况不再存在了。 - oskar132

3

如果你需要动态引用,因为你有一个数组或者其他类似的情况,像我一样。在阅读上面的答案后,这是我想出来的解决方案。

同时,假设myList是一个带有key属性的对象数组。无论如何,你都能理解。

此外,这个解决方案也可以在 TypeScript 中运行而没有任何问题。

const Child = props => <input ref={refElem => setRef(props.someKey, refElem)} />

class Parent extends Component {

    setRef = (key, ref) => {
      this[key] = ref; // Once this function fires, I know about my child :)
    };

    render(){
        return (
          {myList.map(listItem => <Child someKey={listItem.key} setRef={this.setRef} />)}
        )
    }
}

希望这能帮助到某些人。


我有类似的问题,但在React v17中如何使用useRef()解决呢? - Divyank Saxena

0
const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

链接

https://legacy.reactjs.org/docs/forwarding-refs.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接