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, который, как мы уже отмечали точки родитель.