如何使用 React 的上下文功能将 HTML5 Canvas 上下文传递给 this.props.children?
How do I use React's Context feature to pass an HTML5 Canvas context to this.props.children?
我正试图更加熟练地了解 React 如何传递信息,于是出现了这个测试用例:
我有一个组件,由 Canvas object 和不定数量的 children 组成。我想授予 children 访问此组件的 canvas 上下文的权限。
我想知道我是否可以给组件一个带有 canvas 上下文的 React 上下文,并用它包装 children,然后让个人 children 选择成为消费者。但是,我对 React 或其生命周期还不够熟悉,无法知道如何正确地执行此操作。我完全离开了吗?这可能吗?
这是有问题的组件:
const CanvasContext = React.createContext('default');
class Screen extends React.Component
{
render(){
return (<div>
<canvas id="myCanvas" ref={(c) => this.context = c.getContext('2d')} width="200" height="100" style={{border: '1px solid black'}}></canvas>
<CanvasContext.Provider value = {this.context}>{this.props.children}
</CanvasContext.Provider>
</div>);
}
}
现在,它包含一个 child:
class Test extends React.Component{
render(){
return <CanvasContext.Consumer>{ctx => {
ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();}}
</CanvasContext.Consumer>;
}
}
ReactDOM.render(<Screen><Test/></Screen>, document.getElementsByClassName('container-fluid')[0]);
将不胜感激。
编辑:这是一个代码笔:https://codepen.io/ejpg/pen/XqvGdp
这是个好主意,但您有几个问题:
1) 你的codepen中的React版本是15.4
。您正在使用的新上下文 api 是在 16.3
中引入的。这就是您的代码笔抛出错误的原因:
Uncaught TypeError: React.createContext is not a function
2) 当第一次渲染发生时,ref
还不存在,这将导致此函数调用崩溃,因为上下文可能还不存在:
ctx.moveTo(0, 0); // ctx isn't defined yet
ctx.moveTo is not a function
3) 这是使用 16.3
的 createRef
功能的好机会,它有助于管理您的 ref;
class Screen extends React.Component {
canvas = React.createRef();
render() {
return <canvas ref={this.canvas} />
}
}
4) 获取上下文无论如何都需要在第一次渲染之后发生,然后你想在你有上下文传递它时触发重新渲染,所以状态是一个很好的地方:
class Screen extends React.Component {
state = { context: null };
canvas = React.createRef();
componentDidMount() {
this.setState({ context: this.canvas.current.getContext("2d") });
}
render() {
return (
<div>
<canvas ref={this.canvas} />
{this.state.context && (
<CanvasContext.Provider value={this.state.context}>
{this.props.children}
</CanvasContext.Provider>
)}
</div>
);
}
}
这足以让您的测试组件在渲染时绘制!
我正试图更加熟练地了解 React 如何传递信息,于是出现了这个测试用例:
我有一个组件,由 Canvas object 和不定数量的 children 组成。我想授予 children 访问此组件的 canvas 上下文的权限。
我想知道我是否可以给组件一个带有 canvas 上下文的 React 上下文,并用它包装 children,然后让个人 children 选择成为消费者。但是,我对 React 或其生命周期还不够熟悉,无法知道如何正确地执行此操作。我完全离开了吗?这可能吗?
这是有问题的组件:
const CanvasContext = React.createContext('default');
class Screen extends React.Component
{
render(){
return (<div>
<canvas id="myCanvas" ref={(c) => this.context = c.getContext('2d')} width="200" height="100" style={{border: '1px solid black'}}></canvas>
<CanvasContext.Provider value = {this.context}>{this.props.children}
</CanvasContext.Provider>
</div>);
}
}
现在,它包含一个 child:
class Test extends React.Component{
render(){
return <CanvasContext.Consumer>{ctx => {
ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();}}
</CanvasContext.Consumer>;
}
}
ReactDOM.render(<Screen><Test/></Screen>, document.getElementsByClassName('container-fluid')[0]);
将不胜感激。
编辑:这是一个代码笔:https://codepen.io/ejpg/pen/XqvGdp
这是个好主意,但您有几个问题:
1) 你的codepen中的React版本是15.4
。您正在使用的新上下文 api 是在 16.3
中引入的。这就是您的代码笔抛出错误的原因:
Uncaught TypeError: React.createContext is not a function
2) 当第一次渲染发生时,ref
还不存在,这将导致此函数调用崩溃,因为上下文可能还不存在:
ctx.moveTo(0, 0); // ctx isn't defined yet
ctx.moveTo is not a function
3) 这是使用 16.3
的 createRef
功能的好机会,它有助于管理您的 ref;
class Screen extends React.Component {
canvas = React.createRef();
render() {
return <canvas ref={this.canvas} />
}
}
4) 获取上下文无论如何都需要在第一次渲染之后发生,然后你想在你有上下文传递它时触发重新渲染,所以状态是一个很好的地方:
class Screen extends React.Component {
state = { context: null };
canvas = React.createRef();
componentDidMount() {
this.setState({ context: this.canvas.current.getContext("2d") });
}
render() {
return (
<div>
<canvas ref={this.canvas} />
{this.state.context && (
<CanvasContext.Provider value={this.state.context}>
{this.props.children}
</CanvasContext.Provider>
)}
</div>
);
}
}
这足以让您的测试组件在渲染时绘制!