简体   繁体   English

如何使用React的Context功能将HTML5 Canvas上下文传递给this.props.children?

[英]How do I use React's Context feature to pass an HTML5 Canvas context to this.props.children?

I'm trying to become more fluent with how React passes around information, and this test case came up: 我试图让React如何传递信息更加流畅,这个测试案例出现了:

I have a component made up of a Canvas object and an indefinite amount of children. 我有一个由Canvas对象和无限数量的孩子组成的组件。 I would like to give the children access to this component's canvas context. 我想让孩子们访问这个组件的画布上下文。

I was wondering if I could give the component a React Context with the canvas context and wrap the children with it, then have the individual children choose to be consumers. 我想知道我是否可以给组件一个带有画布上下文的React Context并用它包装孩子,然后让个别孩子选择成为消费者。 However, I'm not used to React or its lifecycle enough to know how to do this correctly. 但是,我不习惯React或其生命周期足以知道如何正确地执行此操作。 Am I completely off? 我完全不在了吗? Is this even possible? 这甚至可能吗?

This is the component in question: 这是有问题的组件:

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

  }
}

Right now, it contains one 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]);

Help with this would be greatly appreciated. 对此的帮助将不胜感激。

EDIT: Here's a Codepen: https://codepen.io/ejpg/pen/XqvGdp 编辑:这是一个Codepen: https ://codepen.io/ejpg/pen/XqvGdp

This is a fine idea, but you have a few issues: 这是一个好主意,但你有一些问题:

1) The version of React in your codepen is 15.4 . 1)您的codepen中的React版本是15.4 The new context api which you are using was introduced in 16.3 . 您正在使用的新上下文api在16.3中引入。 This is why your codepen is throwing the error: 这就是你的codepen抛出错误的原因:

Uncaught TypeError: React.createContext is not a function 未捕获的TypeError:React.createContext不是函数

2) When the first render happens, the ref won't exist yet which will cause this function call to crash since the context can't possibly exist yet: 2)当第一次渲染发生时, ref将不存在,这将导致此函数调用崩溃,因为上下文不可能存在:

ctx.moveTo(0, 0); // ctx isn't defined yet

ctx.moveTo is not a function ctx.moveTo不是一个函数

3) This is a great opportunity to use 16.3 's createRef function which helps manage your ref; 3)这是一个使用16.3createRef函数的好机会,它有助于管理你的参考;

class Screen extends React.Component {
  canvas = React.createRef();
  render() {
    return <canvas ref={this.canvas} />
  }
}

4) Getting the context needs to happen after the first render anyway, then you want to trigger a re-render once you have that context to pass it down so state is a good place for that: 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>
    );
  }
}

That's enough to get your Test component to draw on render! 这足以让你的Test组件在渲染上绘制!

Full code on codesandbox 在codeandbox上的完整代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM