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


183

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);

어쩌면 당신은 필요 Pubsub합니까?
slideshowp2

답변:


203

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


따라서 두 하위 구성 요소 사이에 통신하는 유일한 방법은 심판을 가지고 공통 부모에서 프록시 방법을 사용하는 것입니까?
elQueFaltaba

15
React는 데이터 중심 구성 요소를 권장합니다. 한 아이가 조상의 데이터를 변경하는 콜백을 호출하게하고, 그 데이터가 변경되면 다른 아이는 새로운 것을 가져 와서 props다시 렌더링합니다.
Ross Allen

@RossAllen, haha ​​예, 그 경우 세미콜론도 제거해야했을 것입니다.
HussienK

@HussienK 함수에 반환 값이 없어야하는 경우 블록을 사용하는 것이 좋습니다. 따라서 코드를 읽는 다음 개발자에게 의도가 분명합니다. 이를 변경하면 {(child) => this._child = child}항상 반환되는 함수가 생성 true되지만 해당 값은 React의 ref속성에서 사용되지 않습니다 .
Ross Allen

39

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

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

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


1
실제로 그것은 react16에서 작동합니다. ReactDOM 렌더 메소드는 컴포넌트에 대한 참조를 리턴하거나 상태 비 저장 컴포넌트에 대해서는 널을 리턴합니다.
블라드 Povalii

37

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

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

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

1
이에 대한 소스는 여기에 있습니다 .
tirdadc

7

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)

4

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

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

1

당신은 할 수 도하지 않도록 그것이 좋은 계획 인 경우, 다음과 같이 그것을 : 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)
  }
}

1

일부 의견에서 언급했듯이 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();

-1

또 다른 쉬운 방법 :

외부 기능 :

function funx(functionEvents, params) {
  console.log("events of funx function: ", functionEvents);
  console.log("this of component: ", this);
  console.log("params: ", params);
  thisFunction.persist();
}

묶습니다 :

constructor(props) {
   super(props);
    this.state = {};
    this.funxBinded = funx.bind(this);
  }
}

여기에서 완전한 튜토리얼을 참조하십시오 : 외부에서 React Component의 "this"를 사용하는 방법?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.