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

React - How to pass `ref` from child to parent component?

我有一个父组件和一个子组件,我想在我的父组件中访问子组件中元素的 ref。我可以用道具传递吗?

// 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 }/>
    }
}

您可以使用 callback syntax for refs:

// 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} />
    }
}

根据DOC

You may not use the ref attribute on functional components because they don't have instances. You should convert the component to a class if you need a ref to it, just like you do when you need lifecycle methods or state.

所以我认为,如果你想使用 ref,你需要使用 class

检查这个:https://github.com/facebook/react/issues/4936

对于 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} />
    }
}

如果你需要动态引用,因为你有一个数组或其他东西,就像我一样。这是我在阅读上面的答案后想到的。

此外,这还假定 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} />)}
        )
    }
}

无论如何希望这对某人有所帮助。

您可以将 parent 的引用转发给 child - https://reactjs.org/docs/forwarding-refs.html

// Dumb:
export default React.forwardRef((props, ref) => (
   <input type='number' ref={ref} />
));


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

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