reactjs-如何访问父组件中子组件的引用

如果我有类似的东西

<Parent>
  <Child1 />
  <Child2 />
  <Child3 />
</Parent>

我想从Child2访问,那里有refs="child2refs",我该怎么做?

user1354934 asked 2020-07-07T21:28:24Z
6个解决方案
62 votes

推荐用于16.3之前的React版本

如果无法避免,那么从React文档中提取的建议模式将是:

import React, { Component } from 'react';

const Child = ({ setRef }) => <input type="text" ref={setRef} />;

class Parent extends Component {
    constructor(props) {
        super(props);
        this.setRef = this.setRef.bind(this);
    }

    componentDidMount() {
        // Calling a function on the Child DOM element
        this.childRef.focus();
    }

    setRef(input) {
        this.childRef = input;
    }

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

父级转发绑定到父级this的prop函数。当React调用子级ref道具setRef时,它将父级ref分配给子级ref属性。

建议用于React> = 16.3

引用转发是一种选择加入功能,它使某些组件可以接收所接收的引用,并将其进一步向下传递(即“转发”)给孩子。

我们创建将其refReact.forwardRef转发的组件。返回的Component ref prop必须与返回类型React.createRef的类型相同。每当React装入DOM节点时,使用React.createRef创建的ref的属性current便指向基础DOM节点。

import React from "react";

const LibraryButton = React.forwardRef((props, ref) => (
  <button ref={ref} {...props}>
    FancyButton
  </button>
));

class AutoFocus extends React.Component {
  constructor(props) {
    super(props);
    this.childRef = React.createRef();
    this.onClick = this.onClick.bind(this);
  }

  componentDidMount() {
    this.childRef.current.focus();
  }

  onClick() {
    console.log("fancy!");
  }

  render() {
    return <LibraryButton onClick={this.onClick} ref={this.childRef} />;
  }
}

转发参考HOC示例

创建的组件将其ref转发到子节点。

function logProps(Component) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }

    render() {
      const {forwardedRef, ...rest} = this.props;

      // Assign the custom prop "forwardedRef" as a ref
      return <Component ref={forwardedRef} {...rest} />;
    }
  }

  // Note the second param "ref" provided by React.forwardRef.
  // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
  // And it can then be attached to the Component.
  return React.forwardRef((props, ref) => {
    return <LogProps {...props} forwardedRef={ref} />;
  });
}

请参阅React文档中的转发参考。

arpl answered 2020-07-07T21:29:09Z
19 votes
  1. 在子组件内部,向您需要的节点添加引用
  2. 在父组件内部,将引用添加到子组件。
/*
* Child component
*/
class Child extends React.Component {
  render() {
    return (
      <div id="child">
        <h1 ref={(node) => { this.heading = node; }}>
          Child
        </h1>
      </div>
    );
  }
}

/*
 * Parent component
 */
class Parent extends React.Component {
  componentDidMount() {
    // Access child component refs via parent component instance like this
    console.log(this.child.heading.getDOMNode());
  }

  render() {
    return (
      <div>
        <Child
          ref={(node) => { this.child = node; }}
        />
      </div>
    );
  }
}

演示:[https://codepen.io/itsfadnis/pen/aLWVVx?editors=0011]

Nikhil Fadnis answered 2020-07-07T21:29:37Z
15 votes

首先使用以下地址访问孩子:this.props.children,然后每个孩子都将其ref作为财产。

JordanHendrix answered 2020-07-07T21:29:57Z
3 votes

使用引用转发,您可以将引用从父级传递到子级。

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>;
  1. 通过调用React.createRef创建一个React ref并将其分配给ref变量。
  2. 通过将其指定为JSX属性,将您的ref向下传递。
  3. React将ref传递给forwardRef内的(props,ref)=> ...函数作为第二个参数。
  4. 通过将此ref参数指定为JSX属性来向下转发。
  5. 附加ref后,ref.current将指向DOM节点。

注意仅当使用React.forwardRef调用定义组件时,第二个ref参数才存在。 常规函数或类组件不会接收ref参数,并且ref在props中也不可用。

引用转发不限于DOM组件。 您也可以将引用转发到类组件实例。

参考:React文档。

vineet sagar answered 2020-07-07T21:30:53Z
2 votes

这是一个使用refs进行输入的示例(已在React 16.8.6中测试):

子组件:

class Child extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return (<input type="text" ref={this.myRef} />);
  }
}

父组件以及子组件位于其中:

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.childRef = React.createRef();
  }
  componentDidMount() {
    this.childRef.current.myRef.current.focus();
  }
  render() {
    return <Child ref={this.childRef} />;
  }
}

ReactDOM.render(
    <Parent />,
    document.getElementById('container')
);

具有this.props.children的Parent组件:

class Parent extends React.Component {
    constructor(props) {
        super(props);
        this.childRef = React.createRef();
    }
    componentDidMount() {
        this.childRef.current.myRef.current.focus();
    }
    render() {
        const ChildComponentWithRef = React.forwardRef((props, ref) =>
            React.cloneElement(this.props.children, {
                ...props,
                ref
            })
        );
        return <ChildComponentWithRef ref={this.childRef} />
    }
}

ReactDOM.render(
    <Parent>
        <Child />
    </Parent>,
    document.getElementById('container')
);
narmageddon answered 2020-07-07T21:31:26Z
1 votes

我认为本指南对其进行了很好的解释[https://github.com/yannickcr/eslint-plugin-react/issues/678]

class Field extends Component {
  const { inputRef } = this.props;
  render() {
    return (
      <input type="text" ref={inputRef} />
    )
  }
}

class MyComponent extends Component {
  componentDidMount() {
    this.inputNode.focus();
  }

  render() {
    return (
      <div>
        Hello, <Field inputRef={node => this.inputNode = node} />
      </div>
    )
  }
}
OZZIE answered 2020-07-07T21:31:46Z
translate from https://stackoverflow.com:/questions/37647061/how-do-i-access-refs-of-a-child-component-in-the-parent-component