簡體   English   中英

React HTML Canvas不更新

[英]React HTML Canvas Not Updating

我在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;

更新this.props.image (從服務器接收)時,我想在哪里更新畫布。我已經確認我從服務器收到了圖像。這也是我的app.jsx代碼:

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

我沒有收到任何控制台錯誤,但是看不到canvas元素正在更新。 我在setCanvasImage上設置了一個未命中的斷點。 是否由於某種原因未命中componentWillUpdate (調用setCanvasImage )? 如何根據更新后的道具更新畫布元素? 提前致謝。

編輯:

這個問題不是重復的。 盡管該問題是有啟發性的,但我不是從URL加載圖像,而是從base64圖像數據加載圖像。 是的,通過Oboe請求,但是問題不在於服務器沒有提供圖像數據。 如問題所述。 圖像數據已經存在,不必加載。 是的,因為Oboe請求正在進行中,所以它在React組件的初始構建中不存在,但這setCanvasImage何時以及如何調用setCanvasImage ,這是此問題的本質。 它不是重復的,因為另一個問題並未在反應式編程上下文中解決。

初始渲染未調用componentWillUpdate 而是僅在使用新道具觸發組件的重新渲染時才調用它(這就是為什么它將更新生命周期方法)。 如果要在初始渲染上調用setCanvasImage() ,請從componentDidMount調用它。 據我所知,您現在只渲染一次組件。

最好您應該在容器react組件中執行訂閱,然后將DrawingCanvas放在該容器中。 訂閱事件可以更新容器中的狀態,並且可以使用容器的狀態來設置Drawing Canvas的道具。 因此,當接收到圖像時,DrawingCanvas的道具會更新,並且componentWillUpdate將被觸發。

在我看來就像renderDrawingCanvas(); 僅被調用一次。 您可以在ajax回調中重新調用該方法嗎? 還是通過pub-sub在屏幕外調用它?

理想情況下,您的第二段代碼也將是一個React組件,它將圖像保持為狀態。 然后,當其狀態更新時,它將自動重新渲染子DrawingCanvas組件。 我沒有足夠的代表將其保留為評論,因此將其保留為答案...

根據Matt Huggins的建議,請嘗試componentDidUpdate 使用瀏覽器調試器,並確保要放入setCanvasImage內部的條件中。

正如其他人所建議的那樣,您需要在app.jsx中使用某種機制來觸發DrawingCanvas道具進行更新。 這可能是高級React組件,也可能是您自己的控制流程。 訂閱不必是React組件,盡管這不是一個壞方法。 如果需要更新的對象之間具有更復雜的同級關系,則可以進行適當的設置。 image.received訂閱中調用renderDrawingCanvas

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM