Redux: So how to use redux deal with html5 canvas

Created on 21 Jul 2015  ·  3Comments  ·  Source: reduxjs/redux

Hi, I have a project which has a canvas area, and I render the graph (i.e. nodes + edges) in one of 3 static layouts on it. Say on another component (maybe a topnav bar), the user clicks on a button and it should trigger the canvas to animate those nodes and edges, moving them around to change them to another layout among the 3.

So my problem is: in this scenario, apparently the state won't be too useful to render canvas because that's the job of drawing context. However, the canvas still has its "state", which is its layout parameter, but I don't want React to refresh the HTML canvas element once the state.layout is changed because as I said, it's the job of drawing context (and I lose animation if I do that, because it's a re-rendering of the HTML element, not the canvas). Therefore, the only thing I need here is the dispatch between components via Actions.

But in Flux (same for Redux), it is expected to change state to trigger UI re-rendering and the UI is based on the state itself. In canvas, Actions are still expected to trigger the change of the state but the UI (canvas) is rendered by re-drawing.

I'm asking this because only half of my project uses canvas, and there're a lot components which are purely rendered by React (yes, I'm using React but not using Flux pattern). I dislike Flux because it's a bit "over-engineered" in my opinion. Then I found this Redux, which just reduces the part I disliked about Flux. But still, I have this canvas issue, which I'm not sure if it's wise to use Redux or not.

Would you please give me some tips or small code snippet to help? Or if you think it's not proper to use Redux in the project I mentioned above, please tell me that too.

Thanks a million!

P.S. I watched your video on youtube (regarding that react hot loader + Redux speech). Brilliant.

question

Most helpful comment

If I understand you correctly, this is essentially the same problem I recently came across integrating D3 with React. I needed to create the initial <svg> tag and render my state, and then as state changed, initiate d3 animations, add new elements, remove elements, etc.

This StackOverflow article provides an explanation of how to get React to render your <svg> element the first time (or in your case <canvas>, and then have React keep its dirty little fingers off of it, while still giving you a chance to redraw things when the state changes:

Here is the code from the article:

React.createClass({
    render: function() {
        return <svg></svg>;
    },
    componentDidMount: function() {
        d3.select(this.getDOMNode())
            .call(chart(this.props));
    },
    shouldComponentUpdate: function(props) {
        d3.select(this.getDOMNode())
            .call(chart(props));
        return false;
    }
});

The key thing to note is that shouldComponentUpdate() always returns false, so React will never touch that part of the DOM after the initial render.

You should be able to just replace the d3 calls with calls to your rendering code.

All 3 comments

If I understand you correctly, this is essentially the same problem I recently came across integrating D3 with React. I needed to create the initial <svg> tag and render my state, and then as state changed, initiate d3 animations, add new elements, remove elements, etc.

This StackOverflow article provides an explanation of how to get React to render your <svg> element the first time (or in your case <canvas>, and then have React keep its dirty little fingers off of it, while still giving you a chance to redraw things when the state changes:

Here is the code from the article:

React.createClass({
    render: function() {
        return <svg></svg>;
    },
    componentDidMount: function() {
        d3.select(this.getDOMNode())
            .call(chart(this.props));
    },
    shouldComponentUpdate: function(props) {
        d3.select(this.getDOMNode())
            .call(chart(props));
        return false;
    }
});

The key thing to note is that shouldComponentUpdate() always returns false, so React will never touch that part of the DOM after the initial render.

You should be able to just replace the d3 calls with calls to your rendering code.

@mindjuice Thank you so much. This definitely helped me. By the way, I'm rui-infotrack, the author of this question. I was using the company's account previously...

I'm closing, let me know if there's more information about Redux that you need.

Was this page helpful?
0 / 5 - 0 ratings