Sunday, June 2, 2024
 Popular · Latest · Hot · Upcoming
180
rated 0 times [  181] [ 1]  / answers: 1 / hits: 25035  / 7 Years ago, tue, april 25, 2017, 12:00:00

I'm not trying to do anything hacky using refs. 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. Then I pass the <canvas> and this.canvas to the child as two separate props. 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. 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?


More From » reactjs

 Answers
11

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.


[#58027] Friday, April 21, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
aubreeg

Total Points: 437
Total Questions: 102
Total Answers: 102

Location: Colombia
Member since Mon, May 2, 2022
2 Years ago
;