从组件外部访问React组件方法/状态

时间:2018-02-13 15:03:17

标签: javascript html reactjs

我已将reactjs组件嵌入到现有HTML页面中,方法是引用其ID,如React教程中所述:

ReactDOM.render(
  <Page />,
  document.getElementById('my-react-compnent')
);

然后:

<div id="my-react-compnent></div>

组件显示并按预期工作。

现在我想将位于该页面上的按钮链接到我的组件(具体来说我想要检索它的状态,但是对于该示例,即使调用其中一种方法也没问题。)

换句话说 - 当点击外部按钮时,我想调用Page组件中的方法?

我该怎么做?

1 个答案:

答案 0 :(得分:3)

旧建议书

ReactDOM.render分配返回的值确实允许访问组件及其方法。例如,在一个简单的应用程序中,我们可能会:

const PageComponent = ReactDOM.render(<Page />, document.getElementById("app"));

然后我们可以使用PageComponent进行访问,并且可以使用PageComponent.METHOD访问其任何方法。

然而 ,根据文档,这可能会被更改或弃用,不建议使用。

新建议书

新建议是将回调ref附加到根元素。使用上面的相同示例:

const PageComponent = ReactDOM.render(<Page ref={(pageComponent) => {window.pageComponent = pageComponent}}/>, document.getElementById("app"));

然后我们可以使用window.pageComponent进行访问,并且可以使用window.pageComponent.METHOD访问其任何方法。

这也适用于子组件。

以下是一个完整的例子:

&#13;
&#13;
class ChildComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    }
  }

  returnCounter = () => {
    return this.state.counter;
  }
  
  increment = (event) => {
    event.stopPropagation();
    this.setState(prevState => {
      return {
        counter: prevState.counter + 1
      }
    })
  }
  
  render() {
    return (
      <div onClick={this.increment}>
        Child Value - {this.state.counter} - Click to increment
      </div>
    )
  }
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    }
  }

  returnCounter = () => {
    return this.state.counter;
  }
  
  increment = () => {
    this.setState(prevState => {
      return {
        counter: prevState.counter + 1
      }
    })
  }

  render() {
    return (
      <div onClick={this.increment}>
        <div>Parent Value - {this.state.counter} - Click to increment</div>
        <ChildComponent ref={(childComponent) => {window.childComponent = childComponent}}/>
      </div>
    )
  }
}

ReactDOM.render(<Page ref={(pageComponent) => {window.pageComponent = pageComponent}} />, document.getElementById("app"));

const parentBtn = document.getElementById("parentButton");
parentBtn.addEventListener("click", event => {
  alert(window.pageComponent.returnCounter());
});

const childBtn = document.getElementById("childButton");
childBtn.addEventListener("click", event => {
  alert(window.childComponent.returnCounter());
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

<button id="parentButton">Get Parent State</button>
<button id="childButton">Get Child State</button>
&#13;
&#13;
&#13;