Explosion Pills Explosion Pills - 6 months ago 6017
TypeScript Question

Passing a prop to a child created after component mounts

I have a component that is a container for a

<canvas>
. I have other components that take a canvas context as a prop and can be used to manipulate it in various ways; like so:

class App extends React.Component {
ctx: CanvasRenderingContext2D;
canvas: HTMLCanvasElement;

componentDidMount() {
this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D;
this.forceUpdate();
}

render() {
const circle = this.ctx ? <Circle ctx={this.ctx} /> : '';
return (
<canvas ref={ref => (this.canvas = ref as HTMLCanvasElement)}>
{circle}
</canvas>
);
}
}

const Circle = ({ ctx }: { ctx: CanvasRenderingContext2D }) => {
ctx.arc(10, 10, 10, 0, 6);
ctx.stroke();
return null;
};


This works as expected and draws a circle, but I'm not sure that this is the best way to go about it. I have a couple of issues:


  • I'm not sure about the
    forceUpdate
    call.

  • If I don't do the conditional check on
    ctx
    , it will be undefined when Circle first renders.



I was originally using
componentWillMount
, but the problem is that the ref is not set so
this.canvas
is undefined.

Is there a proper way to pass props to child components that depend on refs in the parent?

Answer Source

I think one way to do that would be as below:

class App extends React.Component {
  ctx: CanvasRenderingContext2D;
  canvas: HTMLCanvasElement;

  constructor(props){
     super(props);
     this.state={ ctx:null }
  }

  componentDidMount() {
    this.setState({ctx:this.canvas.getContext('2d') as CanvasRenderingContext2D})
  }

  render() {
    const circle = this.state.ctx? <Circle ctx={this.state.ctx} /> : '';
    return (
      <canvas ref={ref => (this.canvas = ref as HTMLCanvasElement)}>
        {circle}
      </canvas>
    );
  }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download