ctrlplusb / react-tree-walker

Walk a React (or Preact) element tree, executing a "visitor" function against each element.
MIT License
345 stars 34 forks source link

Problems with context using react-jss #30

Open djmccormick opened 6 years ago

djmccormick commented 6 years ago

I'm using mui-org/material-ui (1.0.0-beta.28) and cssinjs/react-jss (8.3.3). When I run reactTreeWalker (4.0.2) against my application, I get an error from JSS that appears to be related to context. My application is able to be rendered without issue using ReactDOMServer.renderToString. I have used reactTreeWalker against this app in the past, but after we upgraded MUI/JSS we started seeing this problem.

react-jss code that might be relevant: https://github.com/cssinjs/react-jss/blob/v8.3.3/src/JssProvider.js#L24

The error:

TypeError: Cannot read property '6fc570d6bd61383819d0f9e7407c452d' of undefined
    at JssProvider.getChildContext (/Users/username/Projects/folder-name/project-name/node_modules/react-jss/lib/JssProvider.js:65:38)
    at /Users/username/Projects/folder-name/project-name/node_modules/react-tree-walker/commonjs/index.js:167:76
    at doTraverse (/Users/username/Projects/folder-name/project-name/node_modules/react-tree-walker/commonjs/index.js:79:68)
    at doVisit (/Users/username/Projects/folder-name/project-name/node_modules/react-tree-walker/commonjs/index.js:116:9)
    at /Users/username/Projects/folder-name/project-name/node_modules/react-tree-walker/commonjs/index.js:142:9
    at new Promise (<anonymous>)
    at reactTreeWalker (/Users/username/Projects/folder-name/project-name/node_modules/react-tree-walker/commonjs/index.js:70:10)
    at router.get (/Users/username/Projects/folder-name/project-name/server/client/server-side-rendering.js:76:2)
    at Layer.handle [as handle_request] (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/layer.js:95:5)
    at /Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:281:22
    at param (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:354:14)
    at param (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:365:14)
    at Function.process_params (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:410:3)
    at next (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:174:3)
    at router (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:317:13)
    at /Users/username/Projects/folder-name/project-name/node_modules/express/lib/router/index.js:284:7

Thanks in advance for any help or guidance you can offer.

kinday commented 6 years ago

Ran into same issue with Styled Components ThemeProvider.

react-tree-walker sets React context to undefined. To work around this issue, pass empty object (or any context object of your choice) as third argument to reactTreeWalker:

import { ThemeProvider } from 'styled-components'
import reactTreeWalker from 'react-tree-walker'
import App from './app'

function visitor(element, instance) {
  // ...
}

const app = (
  <ThemeProvider>
    <App />
  </ThemeProvider>
)

const context = {}

reactTreeWalker(app, visitor, context)
  .then(() => console.log('Works like a charm!'))
  .catch(err => console.error(err))