代码之家  ›  专栏  ›  技术社区  ›  ep84

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

  •  3
  • ep84  · 技术社区  · 7 年前

    我正试图更流利地了解反应如何传递信息,这个测试案例出现了:

    我有一个组件,由画布对象和不确定数量的子对象组成。我想让孩子们访问这个组件的画布上下文。

    我想知道是否可以给组件一个与画布上下文相关的反应上下文,并用它包装孩子们,然后让每个孩子选择成为消费者。但是,我不习惯做出反应,也不习惯它的生命周期,不知道如何正确地做到这一点。我完全离开了吗?这是可能的吗?

    这是有问题的组件:

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

    现在,它包含一个子项:

    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 回复  |  直到 7 年前
        1
  •  4
  •   azium    7 年前

    这是一个好主意,但您有几个问题:

    1)代码笔中的react版本是 15.4 . 在中引入了您正在使用的新上下文API。 16.3 . 这就是您的代码笔抛出错误的原因:

    未捕获的类型错误:React.CreateContext不是函数

    2)当第一次渲染发生时, ref 尚不存在,这将导致此函数调用崩溃,因为上下文尚不可能存在:

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

    ctx.moveto不是函数

    3)这是一个很好的使用机会 十六点三 createRef 帮助管理您的参考号的功能;

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

    这就足够让测试组件在渲染上绘制了!

    Full code on codesandbox

    推荐文章