Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React HTML Canvas Not Updating

I have this code in DrawingCanvas.jsx:

var _ = require('bower.js').lodash;
var React = require('bower.js').React;
var channel = require('com.js').channel;

var DrawingCanvas = React.createClass({
  setCanvasImage: function(){
    if(this.props.image != null)
    {
      //var canvas = React.findDOMNode(this.refs.canvas); // React 0.13 +
      var canvas = this.refs.canvas.getDOMNode();
      var context = canvas.getContext("2d");
      var image = new Image(100,100);
      image.src = 'data:image/png;base64,' + btoa(this.props.image);
      context.drawImage(image, 10, 10);
    }
  },
  componentWillUpdate: function(nextProps, nextState){
    this.setCanvasImage();
  },
  render: function(){
    return (
      <div>
        <canvas ref="canvas" height={this.props.height} width={this.props.width} className="drawing-canvas"></canvas>
      </div>
    );
  }
});

module.exports = DrawingCanvas;

Where I want to update the canvas when this.props.image is updated (received from server. I have verified that I receive the image from the server. Here also is my app.jsx code:

var Oboe = require('bower.js').pOboe;
var channel = require('com.js').channel;

var DrawingCanvas = require('components/DrawingCanvas.jsx');

var cfg = {
  rootApiUrl: 'http://localhost:55474/'
  //rootApiUrl: 'http://trussmgmtdevserver.azurewebsites.net/'
};

var getParameterByName = function(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

var appState = {
    image: null
}

var subscriptions = {
    image: {
        received: channel.sub('image.received', function (image) {
            appState.image = image;
            console.log("RCVD");
        })
    }
};

var renderDrawingCanvas = function (user) {
  React.render(<DrawingCanvas image={appState.image} height={90} width={90}/>, document.querySelector('.canvas-anchor'));
};

renderDrawingCanvas();

Oboe({
        url: cfg.rootApiUrl + 'api/pdfFile/edit?pdfFileId=' + getParameterByName("pdfFileId"),
        method: 'GET'
      }).then(function (data) {
        channel.pub('image.received', data.imageData);
      })
        .catch(function (err) {
          console.error(err);
        });

I receive no console errors, yet I do not see the canvas element updating. I set a breakpoint on setCanvasImage that doesn't get hit. Is componentWillUpdate (which calls setCanvasImage) not being hit for some reason? What can I do to make my canvas element update based on the updated props? Thanks in advance.

Edit:

Not a duplicate of this question. Though that question was instructive, I'm not loading an image from a url, but from base64 image data. Yes, via the Oboe request, but the problem is not that the server isn't providing the image data. It is, as stated in the question. The image data is already there, it doesn't have to be loaded. Yes, it's not there on the initial build of the React component because the Oboe request is in progress, but that comes down to when and how to call setCanvasImage which is the essence of this question. It is not a duplicate because the other question does not address this in a reactive programming context.

like image 359
Scotty H Avatar asked Jun 18 '26 10:06

Scotty H


1 Answers

As suggested by Matt Huggins, try componentDidUpdate. Use the browser debugger and make sure you're dropping into your conditional inside setCanvasImage.

As others have suggested, you need some mechanism in app.jsx that will trigger DrawingCanvas props to update. This could be a high level React component, or your own control flow. The subscriptions do not have to be a React component, though that is not a bad approach. If you have more complicated sibling relationships between objects that need to be updated, your setup can be fitting. Call renderDrawingCanvas from your image.received subscription.

like image 86
jth41 Avatar answered Jun 20 '26 23:06

jth41



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!