2

In a WebWorker, I use ReactDOMServer.renderToString

I then pass that string back to the main UI thread with this:

    lines = lines.map(function(line){
        return ReactDOMServer.renderToString(ContactItem({line: line}));
    });

    postMessage({
        testResult: 'pass',
        testLines: lines
    });

but back in the main UI thread, I am not sure how to actually render that string...do I need to use React.dangerouslySetInnerHTML or is there a better way?

The string result from the WebWorker message looks like this of course:

    MessageEvent bubbles: false 
    cancelBubble: false 
    cancelable: false 
    currentTarget: Worker 
    data: Object 
    name: "chuckles" 
    testLines: Array[25] 

     0: "<li class="Contact" data-reactid=".252oied3u2o" data-react-checksum="1411403885"><h2 class="Contact-name" data-reactid=".252oied3u2o.0">&gt;[test] foo✔</h2></li>" 
     1: "<li class="Contact" data-reactid=".29kk5vm2sqo" data-react-checksum="2115195156"><h2 class="Contact-name" data-reactid=".29kk5vm2sqo.0">&gt;[test] bar✔</h2></li>" 
     2: "<li class="Contact" data-reactid=".bg6xmnuqdc" data-react-checksum="1668960606"><h2 class="Contact-name" data-reactid=".bg6xmnuqdc.0">&gt;[test] baz✔</h2></li>" 
     3: "<li class="Contact" data-reactid=".1t3vx6pj4sg" data-react-checksum="2019185929"><h2 class="Contact-name" data-reactid=".1t3vx6pj4sg.0">&gt;p[test] makes stuff 5✔</h2></li>" 
     4: "<li class="Contact" data-reactid=".cebbpdy8e8" data-react-checksum="818500766"><h2 class="Contact-name" data-reactid=".cebbpdy8e8.0">&gt;p[test] makes stuff 6✔</h2></li>" 
     5: "<li class="Contact" data-reactid=".1bu0bdc3f9c" data-react-checksum="1304319087"><h2 class="Contact-name" data-reactid=".1bu0bdc3f9c.0">&gt;p[test] makes stuff 7✔</h2></li>"

     ...
     25: "<li class="Contact" data-reactid=".1bu6jdc3f9c" data-react-checksum="1404319082"><h2 class="Contact-name" data-reactid=".1bu0bdc3f9c.0">&gt;p[test] makes stuff 25✔</h2></li>"

2 Answers 2

2

dangerouslySetInnerHTML seems to work in this case, but as stated in the documentation:

(1)This functionality is mainly provided for cooperation with DOM string manipulation libraries [...]

Which doesn't seem to the be the case here.

Also, you're manipulating the internals of a component from outside of it. Which, in my experience, could make harder to trace the source of unexpected behavior.

A better way to do it would be to keep processing your list in the WebWorker thread (I imagine you want to make some big computations there) but pass the processed attributes back to the Main UI Thread so they can be passed to the list container that could then generate your list internally.

In a Flux(2) architecture, for example, your store could be responsible for receiving the result of the WebWorker and then pass it to your View, triggering the component render.

Sign up to request clarification or add additional context in comments.

Comments

0

I have a preliminary answer, I think this works, but I am not sure if it fully utilizes the power of the React virtual DOM, even if it is part of the React library.

In my main UI thread, I have this:

     render: function() {

            var self = this;


            var lines = this.state.testLines.map(function (line, i) {
                return React.createElement('div', {key: i, dangerouslySetInnerHTML: {__html: line}});
            });

            return React.createElement('div', {}, lines);

        }

in the worker, I have this:

    if (typeof importScripts === 'function') {
        importScripts('//cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js');
        importScripts('//cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js');
        importScripts('/js/vendor/react-dom-server.js');
        importScripts('//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js');
     }

  onmessage = function (msg) {

    var data = msg.data;

    var lines = doTheThing(data);

    lines = lines.map(function(line){
        return ReactDOMServer.renderToString(ContactItem({line: line}));
    });

    postMessage({
        testResult: 'pass',
        testLines: lines
    });

    close();

};

so the key to getting this to work is to use dangerouslySetInnerHTML like so:

https://facebook.github.io/react/tips/dangerously-set-inner-html.html

this line above being the important line:

return React.createElement('div', {key: i, dangerouslySetInnerHTML: {__html: line}});

...this is the only way I know of rendering a string that is generated on the front-end using a WebWorker.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.