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

Posted

技术标签:

【中文标题】如何使用 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? 【发布时间】:2018-11-06 08:47:00 【问题描述】:

我正在尝试更流畅地了解 React 如何传递信息,结果出现了这个测试用例:

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

我想知道是否可以给组件一个带有画布上下文的 React Context 并用它包装子级,然后让各个子级选择成为消费者。但是,我不习惯 React 或其生命周期,不知道如何正确地做到这一点。我完全没有了?这甚至可能吗?

这是有问题的组件:

const CanvasContext = React.createContext('default');
class Screen extends React.Component
    

  render()

    return (<div>
              <canvas id="myCanvas" ref=(c) => this.context = c.getContext('2d')   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]);

我们将不胜感激。

编辑:这是一个 Codepen:https://codepen.io/ejpg/pen/XqvGdp

【问题讨论】:

【参考方案1】:

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

1) 你的 Codepen 中的 React 版本是15.4。您正在使用的新上下文 API 在 16.3 中介绍。这就是您的 codepen 抛出错误的原因:

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

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

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

ctx.moveTo 不是函数

3) 这是使用16.3createRef 函数来帮助管理您的参考的绝佳机会;

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

【讨论】:

非常感谢您的详细帮助。我会开始做这件事。干杯!

以上是关于如何使用 React 的 Context 功能将 HTML5 Canvas 上下文传递给 this.props.children?的主要内容,如果未能解决你的问题,请参考以下文章

React context API-我如何从 useEffect 钩子中分派一个动作?

在 React.js 的父组件中使用 react-router 时,如何使用 react context API 将数据从父组件传递到子组件?

React Context Hook vs 将数据直接引入组件

如何将 React Context API 与 useReducer 一起使用以遵循与 Redux 类似的风格 [关闭]

如何使用 React Hooks 和 Context API 正确地将来自 useEffect 内部调用的多个端点的数据添加到状态对象?

如何使用 React Context API 跨多个 Routes 拥有状态?