Open KrzysztofKarol opened 7 years ago
Hi @KrzysztofKarol, thank you for reporting this! I was actually unaware of how/if this library worked with SSR.
The source doesn't make any reference to document
/window
, so seems to be a bundling/dependency issue, will look into this after work today.
As a workaround until this is implemented you could maybe render the tree on componentDidMount
to ensure it renders in the client?
Hi @bkrem Thank you for your almost instantaneous answer. Yes, I checked that too. I built it without UglifyJsPlugin and it's used for
isOldIE = memoize(function() {
// Test for IE <= 9 as proposed by Browserhacks
// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
// Tests for existence of standard globals is to allow style-loader
// to operate correctly into non-standard environments
// @see https://github.com/webpack-contrib/style-loader/issues/177
return window && document && document.all && !window.atob;
}),
I investigated problem a little
https://github.com/webpack-contrib/style-loader/blob/67120f8dc831626f466d64513b4e26074e89341b/lib/addStyles.js#L23
Problem occures during import
// react-d3-tree.js
module.exports = function(list, options) {
// Here DEBUG is not defined
if (typeof DEBUG !== "undefined" && DEBUG) {
if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
}
options = options || {};
options.attrs = typeof options.attrs === "object" ? options.attrs : {};
// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
// tags it will allow on a page
if (!options.singleton) options.singleton = isOldIE();
Ahh interesting, thanks for digging into this already.
Seems like the least path of resistance would be to set options.singleton
if it's part of the style-loader
public API since IE 8 and older isn't supported by the React team anymore anyways.
Otherwise it would be worth working around the style-loader
plugin if that gets SSR working.
If you have an idea feel free to put in a PR @KrzysztofKarol, otherwise I'll check this out in detail this evening :)
I couldn't find simple and good solution. So i made it very dirty way for now - I used isomorphic-style-loader instead of style-loader. https://github.com/KrzysztofKarol/react-d3-tree/commit/f876afec64f5fbc1932f950c481a2b8ae9d032bc
BTW. I also encountered a problem with react-transition-group
. react-d3-tree uses 1.1.3 as external and it's somehow overriding 2.2.1 used by material-ui@next.
Ok cool, good to hear you found a way. If isomorphic-style-loader
seems to do the job I'll move the build pipeline to that.
Ok that's a strange one regarding react-transition-group
, might make sense to bundle the dependencies directly rather than using externals in that case.
Thanks for reporting these two already, super useful! 🙌
@bkrem @KrzysztofKarol Is this issue fixed? Somehow I'm still seeing the same error during server side rendering.
amazing work by the way, looking forward to using it!
Hi @codemonkeycxy!
I wasn't using this lib for months so you have to ask @bkrem directly.
Hi @codemonkeycxy,
SSR still isn't technically supported. I spent an entire day at the time tinkering with the isomorphic loader that Krzysztof suggested (and one or two other ones).
I couldn't get a stable version out of it and there were more pressing issues to resolve with the library so I closed this as out of scope (sorry for my lack of explanation when I closed it), since this error is preventable if you await componentDidMount()
like so:
class MyTreeComponent extends React.PureComponent {
state = {
didMount: false
}
componentDidMount() {
this.setState({
didMount: true
})
}
render() {
<div>{this.state.didMount && <Tree />}</div>
}
}
I'm aware that this isn't optimal (setState
in componentDidMount
will cause an extra render call) and adds some boilerplate, but I simply haven't had the time to get the SSR issue resolved recently.
I hope this helps as a workaround for now and I will obviously update the issue once a fix is in place!
@codemonkeycxy you can also use npm's package react-no-ssr as a workaround
https://github.com/kadirahq/react-no-ssr/blob/master/src/index.js
@KrzysztofKarol How is this meant to be used?
I see it's a component on NPM now, but I'm still getting window is not defined when used like:
const Root = () => (
<Provider store={store}>
<NoSSR>
<ComponentThatUsesWindow />
</NoSSR>
</Provider>
)
@thomashibbard I think yes but this repo has latest commit dated on 9 Apr 2016 so I don't know how does it work with latest React versions. You can report an issue https://github.com/kadirahq/react-no-ssr/issues but I think that no one is maintaining this lib anymore, sadly.
@thomashibbard same window not defined issue even with NoSSR. I finally got it working by doing a inline import
const Tree = require('react-d3-tree').Tree;
return (
<div style={{width: '100vw', height: '100vh'}}>
<Tree data={data} onClick={this.onClick} />
</div>
);
let Tree = ' '
class MyComponent extends React.PureComponent {
state = {
redender: false
};
async componentDidMount() {
let res = await import("react-d3-tree");
Tree = res.Tree;
this.setState({ redender: true, window });
}
render() {
return <div style={{ height: 1000, width: 1000 }}>{this.state.redender && <Tree data={myTreeData} />}</div>;
}
}
this worked for me
If anyone is still strugling ?
For Imports if (canUseDOM()) { const ReactD3Tree = require('react-d3-tree'); Tree = ReactD3Tree.default; }
For Usage if (!canUseDOM()) return null; return ( <div className="react-tree" id="treeWrapper" style={{ width: '150em', height: '150em' }}> <Tree {...props} />
Function (canUseDOM) export function canUseDOM() { return !!(typeof window !== 'undefined' && window.document && window.document.createElement); }
Any update with integration of this to Gatsby?
How to use this great library properly with Server-Side Rendering (SSR)
return window&&document&&document.all&&!window.atob