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

IT技术 javascript html reactjs
2021-05-24 19:38:41

我已经reactjs通过引用它的 ID 将一个组件嵌入到现有的 HTML 页面中,如 React 教程中所述:

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

然后:

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

该组件已显示并按预期工作。

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

换句话说 - 单击外部按钮时,我想从Page组件调用一个方法

我怎样才能做到这一点?

1个回答

旧建议

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

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

然后我们可以使用 using 访问它PageComponent,并且可以使用 访问它的任何方法PageComponent.METHOD

但是,根据文档,这可能会被更改或弃用,因此不推荐使用。

新推荐

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

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

然后我们可以使用 using 访问它window.pageComponent,并且可以使用 访问它的任何方法window.pageComponent.METHOD

这也适用于子组件。

这是一个完整的例子:

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