我不是想用refs做任何hacky。我只需要对元素的引用,因为元素是一个画布,并且要在画布上绘制,你需要它的参考。
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
作为两个单独的道具传递给孩子。我在子项的render函数中返回<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;
}
}
是否有更标准的方法来实现这一目标?
答案 0 :(得分:6)
您实际应该使用第一种方法,并且可以访问父
中的子元素引用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
。
答案 1 :(得分:2)
如果无法避免,则从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} />
}
}
父将函数作为绑定传递给父的this
。 React会调用孩子的ref
回调setRef
并将childInput
属性附加到this
,正如我们已经指出的那样父。