React-получить ref присутствует в дочернем компоненте в Родительском компоненте

Я не пытаюсь сделать что-нибудь хакерское с помощью refs. Мне просто нужен ref для элемента, потому что элемент-это холст, и для рисования на холсте вам нужен его 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>
    );
  }
}

=====

то, что я пробовал (что технически работает, но чувствует себя странно), определяет <canvas> в родителе, поэтому в его функции ref,this относится к родительскому компоненту. Затем я передаю <canvas> и this.canvas ребенку как два отдельных реквизита. Я возвращаю <canvas> (по имени this.props.canvasJSX) в функции рендеринга ребенка, и я использую this.canvas (название this.props.canvasRef), чтобы получить контекст, чтобы рисовать на нем. См. ниже:

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

есть ли более стандартный способ достижения этой цели?

2 ответов


вы должны фактически использовать первый подход, и вы можете получить доступ к дочерним элементам refs в Родительском

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

вы можете использовать только этот подход, дочерний компонент объявлен как class.


если этого нельзя избежать, предложенный шаблон, извлеченный из React docs будет:

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} />
    }
}

на родитель передает функцию как опору, привязанную к родитель ' s this. React вызовет ребенок ' s ref обратный звонок setRef и прикрепите childInput свойство this, который, как мы уже отмечали точки родитель.