[javascript] ReactJS의“외부”에서 컴포넌트 메소드에 액세스하는 방법은 무엇입니까?

ReactJS의“외부”에서 컴포넌트 메소드에 액세스 할 수없는 이유는 무엇입니까? 왜 불가능하고 해결 방법이 있습니까?

코드를 고려하십시오 :

var Parent = React.createClass({
    render: function() {
        var child = <Child />;
        return (
            <div>
                {child.someMethod()} // expect "bar", got a "not a function" error.
            </div>
        );
    }
});

var Child = React.createClass({
    render: function() {
        return (
            <div>
                foo
            </div>
        );
    },
    someMethod: function() {
        return 'bar';
    }
});

React.renderComponent(<Parent />, document.body);



답변

React는 ref속성을 통해 수행하려는 작업에 대한 인터페이스를 제공 합니다 . 구성 요소 a를 지정하면 ref해당 current속성이 사용자 정의 구성 요소가됩니다.

class Parent extends React.Class {
    constructor(props) {
        this._child = React.createRef();
    }

    componentDidMount() {
        console.log(this._child.current.someMethod()); // Prints 'bar'
    }

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

참고 : 이것은 https://facebook.github.io/react/docs/refs-and-the-dom.html#adding-a-에 있는 하위 구성 요소가 클래스로 선언 된 경우에만 작동합니다. 클래스 구성 요소에 대한 참조

2019-04-01 업데이트 : 클래스 및 createRef최신 React 문서 를 사용하도록 예제가 변경되었습니다 .

업데이트 2016년 9월 19일 : 변경된 예에서 지침 당 심판 콜백을 사용하는 문자열 속성 문서.ref


답변

React 외부에서 컴포넌트에 대한 함수를 호출하려는 경우 renderComponent의 리턴 값에서 함수를 호출 할 수 있습니다.

var Child = React.createClass({…});
var myChild = React.renderComponent(Child);
myChild.someMethod();

React 외부의 React Component 인스턴스에 대한 핸들을 얻는 유일한 방법은 React.renderComponent의 반환 값을 저장하는 것입니다. 소스 .


답변

또는 Child의 메소드가 진정으로 정적 인 경우 (현재 소품의 상태가 아닌 상태) statics정적 클래스 메소드와 마찬가지로 메소드를 정의한 다음 액세스 할 수 있습니다. 예를 들면 다음과 같습니다.

var Child = React.createClass({
  statics: {
    someMethod: function() {
      return 'bar';
    }
  },
  // ...
});

console.log(Child.someMethod()) // bar


답변

React 16.3 부터 React.createRef사용 가능 ( ref.current액세스에 사용 )

var ref = React.createRef()

var parent = <div><Child ref={ref} /> <button onClick={e=>console.log(ref.current)}</div>

React.renderComponent(parent, document.body)


답변

React 0.12부터 API가 약간 변경되었습니다 . myChild를 초기화하는 유효한 코드는 다음과 같습니다.

var Child = React.createClass({…});
var myChild = React.render(React.createElement(Child, {}), mountNode);
myChild.someMethod();


답변

당신은 할 수 도하지 않도록 그것이 좋은 계획 인 경우, 다음과 같이 그것을 : D

class Parent extends Component {
  handleClick() {
    if (this._getAlert !== null) {
      this._getAlert()
    }
  }

  render() {
    return (
      <div>
        <Child>
        {(getAlert, childScope) => (
          <span> {!this._getAlert ? this._getAlert = getAlert.bind(childScope) : null}</span>
        )}
        </Child>
        <button onClick={() => this.handleClick()}> Click me</button>
      </div>
      );
    }
  }

class Child extends Component {
  constructor() {
    super();
    this.state = { count: 0 }
  }

  getAlert() {
    alert(`Child function called state: ${this.state.count}`);
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return this.props.children(this.getAlert, this)
  }
}


답변

일부 의견에서 언급했듯이 ReactDOM.render더 이상 구성 요소 인스턴스를 반환하지 않습니다. 다음 ref과 같이 구성 요소의 루트를 렌더링 할 때 콜백을 전달 하여 인스턴스를 가져올 수 있습니다.

// React code (jsx)
function MyWidget(el, refCb) {
    ReactDOM.render(<MyComponent ref={refCb} />, el);
}
export default MyWidget;

과:

// vanilla javascript code
var global_widget_instance;

MyApp.MyWidget(document.getElementById('my_container'), function(widget) {
    global_widget_instance = widget;
});

global_widget_instance.myCoolMethod();