在ref内部渲染ReactPortal

时间:2018-11-13 13:56:23

标签: javascript reactjs typescript

我想要实现的是在ref内部渲染ReactPortal,从而在React Application本身内部渲染,而不是外部的DOM节点。

我在Codepen上做了一个例子-> https://codepen.io/Gesma94/pen/RqKZmM

class Legend extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    if (this.props.useRef)
      return ReactDOM.createPortal(<div className="legend">Something</div>, this.props.ref);
    else
      return <div className="legend">Something else</div>;
  }
}

class Chart extends React.Component {
  private myref;

  render() {
        return (
      <div>
        <div className="container" ref={r => this.myref = r}>First Container</div>
        <Legend ref={this.myref} useRef={false} />
      </div>
    );
  }
}

ReactDOM.render(<Chart />, document.getElementById('root'));

因此,基本上:在Chart组件内部,我保存了第一个div的引用,然后将该引用传递给Legend组件。 在图例组件内部,如果props useRef为true,则我想使用createPortal()在图表的div内返回一个div。

问题在于React向我抛出错误:TypeScript告诉我“类型'RefOject'的参数不能分配给'元素'类型的参数。

现在,我什至不知道我想做的事是否可能,但是如果可以,你们能帮我些忙吗?也许我缺少了ref(我想是有些转换,但我真的不知道该怎么办)。

谢谢!

1 个答案:

答案 0 :(得分:2)

首先必须确保已创建引用,即在首次安装组件时即已创建。 React在内部使用ref道具,就像key道具一样,因此您必须为其命名,并像对待其他道具一样对待它。

示例

class Legend extends React.Component {
  render() {
    if (this.props.useRef) {
      return ReactDOM.createPortal(
        <div className="legend">Something</div>,
        this.props.portalRef
      );
    }
    return <div className="legend">Something else</div>;
  }
}

class Chart extends React.Component {
  myref = null;
  state = { mounted: false };

  componentDidMount() {
    // The ref has been created when the component has mounted.
    this.setState({ mounted: true });
  }

  render() {
    return (
      <div>
        <div className="container" ref={r => this.myref = r}>
          First Container
        </div>
        {this.state.mounted && <Legend portalRef={this.myref} useRef />}
      </div>
    );
  }
}

ReactDOM.render(<Chart />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"><div>