简体   繁体   English

React - 获取父组件中子组件中的ref

[英]React - Get the ref present in child component in the parent component

I'm not trying to do anything hacky using refs. 我不是想用refs做任何hacky。 I just need the ref to the element because the element is a canvas, and to draw on a canvas you need its ref. 我只需要对元素的引用,因为元素是一个画布,要在画布上绘制,你需要它的引用。

class Parent extends Component {
  clickDraw = () => {
    // when button clicked, get the canvas context and draw on it.
    // how?
  }

  render() {
    return (
      <div>
        <button onClick={this.clickDraw}> Draw </button>
        <Child />
      </div>
    );
  }
}


class Child extends Component {
  componentDidMount() {
    const ctx = this.canvas.getContext('2d');
    // draw something on the canvas once it's mounted
    ctx.fillStyle = "#FF0000";
    ctx.fillRect(0,0,150,75);
  }

  render() {
    return (
      <canvas width={300}
              height={500}
              ref={canvasRef => this.canvas = canvasRef}>
      </canvas>
    );
  }
}

===== =====

Something I tried (which technically works but feels strange) is define the <canvas> in the parent, so in its ref function, this refers to the parent component. 我尝试过的东西(技术上有效,但感觉很奇怪)是在父类中定义<canvas> ,因此在它的ref函数中, this指的是父组件。 Then I pass the <canvas> and this.canvas to the child as two separate props. 然后我将<canvas>this.canvas作为两个独立的道具this.canvas给子this.canvas I return the <canvas> (named this.props.canvasJSX ) in the child's render function, and I use this.canvas (named this.props.canvasRef ) to get its context to draw on it. 我在子的render函数中返回<canvas> (名为this.props.canvasJSX ),并使用this.canvas (名为this.props.canvasRef )来获取其上下文。 See below: 见下文:

class Parent extends Component {
  clickDraw = () => {
    // now I have access to the canvas context and can draw
    const ctx = this.canvas.getContext('2d');
    ctx.fillStyle = "#00FF00";
    ctx.fillRect(0,0,275,250);
  }

  render() {
    const canvas = (
      <canvas width={300}
              height={500}
              ref={canvasRef => this.canvas = canvasRef}>
      </canvas>
    );
    return (
      <div>
        <button onClick={this.clickDraw}> Draw </button>
        <Child canvasJSX={canvas}
               canvasRef={this.canvas} />
      </div>
    );
  }
}


class Child extends Component {
  componentDidMount() {
    const ctx = this.props.canvasRef.getContext('2d');
    // draw something on the canvas once it's mounted
    ctx.fillStyle = "#FF0000";
    ctx.fillRect(0,0,150,75);
  }

  render() {
    return this.props.canvas;
  }
}

Is there a more standard way of achieving this? 是否有更标准的方法来实现这一目标?

You should actually be using the first approach and you can access the child elements refs in the parent 您应该实际使用第一种方法,并且可以访问父级中的子元素引用

class Parent extends Component {
  clickDraw = () => {
    // when button clicked, get the canvas context and draw on it.
    const ctx = this.childCanvas.canvas.getContext('2d');
    ctx.fillStyle = "#00FF00";
    ctx.fillRect(0,0,275,250);
  }

  render() {
    return (
      <div>
        <button onClick={this.clickDraw}> Draw </button>
        <Child ref={(ip) => this.childCanvas = ip}/>;
      </div>
    );
  }
}


class Child extends Component {
  constructor() {
     super();
     this.canvas = null;
  }
  componentDidMount() {
    const ctx = this.canvas.getContext('2d');
    // draw something on the canvas once it's mounted
    ctx.fillStyle = "#FF0000";
    ctx.fillRect(0,0,150,75);
  }

  render() {
    return (
      <canvas width={300}
              height={500}
              ref={canvasRef => this.canvas = canvasRef}>
      </canvas>
    );
  }
}

You can only use this approach is the child component is declared as a class . 您只能使用此方法将子组件声明为class

If it cannot be avoided the suggested pattern extracted from the React docs would be: 如果无法避免,从React文档中提取的建议模式将是:

import React, {Component} from 'react';

const Child = ({setRef}) => <input type="text" ref={setRef} />;

class Parent extends Component {
    constructor(props) {
        super(props);
        this.setRef = this.setRef.bind(this);
    }
    componentDidMount() {
        // Call function on Child dom element
        this.childInput.focus();
    }
    setRef(input) {
        this.childInput = input;
    }
    render() {
        return <Child setRef={this.setRef} />
    }
}

The Parent passes a function as prop bound to Parent 's this . 通过绑定到的函数,如丙this React will call the Child 's ref callback setRef and attach the childInput property to this which as we already noted points to the Parent . React将调用Childref回调setRef并将childInput属性附加到this ,正如我们已经指出的那样指向Parent

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM