Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

this.context.muiTheme is undefined #686

Closed
super-cache-money opened this issue May 25, 2015 · 35 comments
Closed

this.context.muiTheme is undefined #686

super-cache-money opened this issue May 25, 2015 · 35 comments
Labels
customization: theme Centered around the theming features

Comments

@super-cache-money
Copy link
Contributor

I've tried to use 0.8 with both React 13.3 and React 13.1.

I've tried a few components, including RaisedButton, and Checkbox.

As the title states, rendering breaks with the following error:

TypeError: Cannot read property 'component' of undefined

muiTheme is undefined.

I've triple checked my node_modules directory; there's only one version of react in there.
There are no warnings, other than this old one:

Warning: bind(): React component methods may only be bound to the component instance. See exports

Inserting this:

contextTypes: {
    muiTheme: React.PropTypes.object.isRequired
}

gives the following warning:

Failed Context Types: Required context muiTheme was not specified in MyOtherwiseWorkingComponent. Check the render method of exports.

I'm so eager to try this out! What could be the issue here?

@SebT
Copy link

SebT commented May 25, 2015

Same here: #682

I can't make it work either :(

@wmertens
Copy link

See https://github.com/callemall/material-ui/blob/master/example/src/app/components/main.jsx#L5-L24, you have to add it manually now.

@SebT
Copy link

SebT commented May 25, 2015

I did add it. Then I had: Warning: owner-based and parent-based contexts differ (values:undefinedvs[object Object]) for key (muiTheme) while mounting TextField (see: http://fb.me/react-context-by-parent)

@super-cache-money
Copy link
Contributor Author

@wmertens That really helped!
I've added

childContextTypes: {
    muiTheme: React.PropTypes.object
},

getChildContext: function() {
    console.log('setting context!!');
    return {
        muiTheme: ThemeManager.getCurrentTheme()
    };
},

However, I'm still somehow getting the same error, when using, for example, RaisedButton.
muiTheme is undefined.

Upon some investigation, I found that within render() of RaisedButton itself, this.context.muiTheme is indeed defined. However, within the subcomponent Paper's render(), this.context.muiTheme is undefined. Perhaps it's worth mentioning that the error originates from getStyles() within the Paper class. Furthermore, this happens only in the browserified bundle. It's fine rendering on the server. Weird!

What could be causing this?

@super-cache-money
Copy link
Contributor Author

Figured it out.
In the browser, I had two versions of react running.

This is probably not relevant for most people, but here's more info:

I'm using browserify and browserify-shim to bundle scripts. The shim transform wasn't set to global, so when a package in node_modules required react (like material-ui, in this case), the shim isn't applied and the whole library is inlined.

@wmertens
Copy link

@SebT I'm seeing the same, I have a component that simply adds this.props.children to its createElement call and it looks like they lose their context then. No time to investigate right now

@wmertens
Copy link

@SebT: context seems to suck: acdlite/flummox#70 (comment)
I also get that warning and my FlatButton doesn't render.

@super-cache-money facebook/react#1939 strikes again

@wmertens
Copy link

@SebT I solved it for me with this non-perfect solution (CoffeeScript): Instead of using @props.children I use @props.children.map (c, i) -> React.addons.cloneWithProps c, key: i.

There are several things wrong with that, it should really use the ReactChildren iteration and it shouldn't replace the key if one is there, but in my case that doesn't matter and probably won't until 0.14 comes out.

@SebT
Copy link

SebT commented May 27, 2015

Well I tried again yesterday and this time it did work with childContext.

I don't really know what happened, I re-ran a npm install for another reason and maybe I had another version of React in my node_modules.

Anyway, thanks for the help @wmertens ;)

@agnivade
Copy link
Contributor

agnivade commented Aug 7, 2015

@super-cache-money - I might have a similar issue which I am unable to solve. I am using webpack to convert the material-ui library and use it in the browser. I think that inlines the react library in that file itself.

Now I also have an external reference to a react library from my main html file <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>

Is this why this conflict is happening ? Any way to work around it ?

@p4004
Copy link

p4004 commented Aug 13, 2015

I will post how I solved this problem: I was including 'react/addons' in my vendors bundle file using browserify. However in my components I was requiring react in this way:

import React from 'react'; (not 'react/addons')

Once I changed 'react/addons' to 'react' in my vendors bundle file, error dissapeared.

@Qrysto
Copy link

Qrysto commented Aug 23, 2015

I still can't make this to work. I use react-router@1.0.0-beta3 and my router is like

<Router history={history}>
    <Route path="/" component={App}>
        <Route path="somePage" component={somePage} />
    </Route>
</Router>

I've already define getChildContext() in App component

export default class App extends React.Component {
    static childContextTypes = {
        muiTheme: PropTypes.object
    }
    getChildContext() {
        return {
            muiTheme: ThemeManager.getCurrentTheme()
        }
    }
    render() {
        return (
            <div>
                {this.props.children}
            </div>
        );
    }
}

in somePage component I use some material UI components, and I get this warning

"Warning: owner-based and parent-based contexts differ (values: `undefined` vs `[object Object]`) for key (muiTheme) while mounting TextField (see: http://fb.me/react-context-by-parent)" 

and this error

Uncaught TypeError: Cannot read property 'component' of undefined

it was because this.context.muiTheme is undefined. What else do I have to do?

@wmertens
Copy link

Use React 0.14 beta or clone the children.

On Sun, Aug 23, 2015, 08:14 Qrysto notifications@github.com wrote:

I still can't make this to work. I use react-router@1.0.0-beta3 and my
router is like

I've already define getChildContext() in App component

export default class App extends React.Component {
static childContextTypes = {
muiTheme: PropTypes.object
}
getChildContext() {
return {
muiTheme: ThemeManager.getCurrentTheme()
}
}
render() {
return (


{this.props.children}

);
}
}

in somePage.jsx I use some material UI components, and I get this warning

"Warning: owner-based and parent-based contexts differ (values: undefined vs [object Object]) for key (muiTheme) while mounting TextField (see: http://fb.me/react-context-by-parent)"

and this error

Uncaught TypeError: Cannot read property 'component' of undefined

it was because this.context.muiTheme is undefined. What else should I have
to do?


Reply to this email directly or view it on GitHub
#686 (comment)
.

Wout.
(typed on mobile, excuse terseness)

@Qrysto
Copy link

Qrysto commented Aug 23, 2015

now the problem is

peerinvalid Peer react-tap-event-plugin@0.1.7 wants react@~0.13.x || ~0.12.x

when i try to install react@0.14.0-beta1 😆 . Btw what do you mean by "clone the children"?

@wmertens
Copy link

you can drop the tap-event plugin in react 0.14 I think :)

when you clone the children, they get a new owner (you) and the context works. See #686 (comment)

@wmertens
Copy link

Oh, the plugin is needed until React 1.0: https://github.com/zilverline/react-tap-event-plugin

@sathify
Copy link

sathify commented Aug 24, 2015

@wmertens thanks for the help. What exactly do you mean by cloning the children? @Qrysto I have this problem when I try to upgrade to react 0.14 beta. How are you solving it?

npm ERR! Darwin 13.4.0
npm ERR! argv "node" "/usr/local/bin/npm" "install"
npm ERR! node v0.10.33
npm ERR! npm  v2.1.7
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package react does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer fluxible-addons-react@0.1.6 wants react@0.13.x
npm ERR! peerinvalid Peer fluxible-router@0.2.1 wants react@0.13.x
npm ERR! peerinvalid Peer react-tap-event-plugin@0.1.7 wants react@~0.13.x || ~0.12.x
npm ERR! peerinvalid Peer material-ui@0.10.4 wants react@>=0.13

npm ERR! Please include the following file with any support request:

@Qrysto
Copy link

Qrysto commented Aug 24, 2015

@sathify actually I haven't solved it yet 😆 Probably I'll ready more about that "cloning the children" when I have time, but I wonder how people can still use MUI at the moment ❓

@soda29
Copy link

soda29 commented Aug 27, 2015

Having the same problem with react-router@1.0.0-beta3, right now don't know if that is the cause of the problem

@nickspacek
Copy link

I upgraded to react@0.14.0-beta3 and the problem went away for me. Don't need react-tap-event-plugin (gives an error) and had to edit the node_modules/material-ui/package.json to remove the peerDependency. Messy workaround for that, but works.

@sathify YMMV with those fluxible peerDependencies.

@sathify
Copy link

sathify commented Sep 4, 2015

@Vijar This is what I was talking about - any chance the fluxible modules work with react@0.14.0-beta3? Thanks much.

@Vijar
Copy link

Vijar commented Sep 5, 2015

@sathify I don't think you need to upgrade to React0.14 to get material-ui to work.

If you're using provideContext with fluxible you can just do this:

Application = provideContext(Application, {
    muiTheme: React.PropTypes.object
});

Then for actually setting the child context properly use this gist as a plugin and plug it into your fluxible app.

After that, everything should work.

Maybe open an issue on fluxible repo if you want to talk about this some more.

@bigdrum
Copy link

bigdrum commented Sep 5, 2015

This is an issue of react-router 1.0.0, here is a workaround:
remix-run/react-router#1301 (comment)

@Vijar
Copy link

Vijar commented Sep 11, 2015

@sathify as far as fluxible + material-ui: https://github.com/Vijar/fluxible-plugin-material-ui

@sathify
Copy link

sathify commented Sep 11, 2015

@Vijar thanks. This seems like a better way to do it with fluxible, plugging the context. I however just initiallized in the root component.

@cgestes
Copy link
Contributor

cgestes commented Sep 26, 2015

I confirm that the issue disappear when using React 0.14.0 (-rc1)

@camerow
Copy link

camerow commented Oct 8, 2015

I get that React 0.14 solves this, but I'm confused at how to update to that when the current material-ui module does not support it as a dependency. Tried -f to no avail.

@catamphetamine
Copy link

catamphetamine commented Oct 4, 2016

import getMuiTheme from 'material-ui/styles/getMuiTheme'
...


    static childContextTypes =
    {
        muiTheme: React.PropTypes.object
    }

    getChildContext()
    {
        return {
            muiTheme: getMuiTheme()
        }
    }

@rafaeleyng
Copy link

@halt-hammerzeit where should I put this?

In my scenario, I'm using Material-UI and trying to test it with Enzyme. But for my components do work properly I have to render them with MuiThemeProvider around. But now I can't get the state() (from Enzyme) from my components, only to the root, that I believe to be MuiThemeProvider itself

@ca0abinary
Copy link

ca0abinary commented May 26, 2017

@rafaeleyng I got this working with shallow, but not mount yet.

Helper function:

import { getMuiTheme } from 'material-ui/styles';
const muiTheme = getMuiTheme();

export const shallowWithMuiThemeContext = node =>
  shallow(node, { context: { muiTheme } });

// For traditional react-test-renderer usage:
export const createWithMuiTheme = node =>
  renderer.create(React.createElement(MuiThemeProvider, null, node));

Example usage in unit test:

const myComponent = shallowWithMuiThemeContext(<MyComponent />);
myComponent.instance().funcThatChangesState(expectedStateChangeObject);

expect(myComponent.state('stateObjectFieldSetByAboveFunc')).toBe(
  expectedStateChangeObject
);

@abrjagad
Copy link

The docs are updated.

import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import MyAwesomeReactComponent from './MyAwesomeReactComponent';

const App = () => (
  <MuiThemeProvider>
    <MyAwesomeReactComponent />
  </MuiThemeProvider>
);

@eromoe
Copy link

eromoe commented Sep 5, 2017

I wonder which level to put MuiThemeProvider ?

const render = (messages) => {
  ReactDOM.render(
    <Provider store={store}>
      <LanguageProvider messages={messages}>
        <ConnectedRouter history={history}>
          <App />
        </ConnectedRouter>
      </LanguageProvider>
    </Provider>,
    MOUNT_NODE
  );
};

Now I put it in App ,

    <MuiThemeProvider>
      <Switch>
        <Route exact path="/" component={HomePage} />
        <Route path="/corpus/:corpusId" component={CorpusPage} />
        <Route component={NotFoundPage} />
      </Switch>
    </MuiThemeProvider>

but got

warning.js:35 Warning: Failed prop type: The prop `theme` is marked as required in `MuiThemeProvider`, but its value is `undefined`.
    in MuiThemeProvider (created by App)
    in App
    in Router (created by ConnectedRouter)
    in ConnectedRouter
    in IntlProvider (created by LanguageProvider)
    in LanguageProvider (created by Connect(LanguageProvider))
    in Connect(LanguageProvider)
    in Provider

if I write like

const render = (messages) => {
  ReactDOM.render(
    <MuiThemeProvider>
      <Provider store={store}>
        <LanguageProvider messages={messages}>
          <ConnectedRouter history={history}>
            <App />
          </ConnectedRouter>
        </LanguageProvider>
      </Provider>
    </MuiThemeProvider>,
    MOUNT_NODE
  );
};

still got

Warning: Failed prop type: The prop `theme` is marked as required in `MuiThemeProvider`, but its value is `undefined`.
    in MuiThemeProvider

@catamphetamine
Copy link

Provide theme property for <MuiThemeProvider/>

@eromoe
Copy link

eromoe commented Sep 5, 2017

@catamphetamine Isn't there a default theme already ?

@catamphetamine
Copy link

@eromoe dunno, not using this library

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
customization: theme Centered around the theming features
Projects
None yet
Development

No branches or pull requests