How to fix problem with createGenerateClassName() and jssPreset() when migrating from material-ui v3 to v4?

Viewed 5486

Had material-ui v3 working on a messaging app and was using createGenerateClassName() and jssPreset() to configure the JSS to allow for right-to-left text direction.

Upon upgrading to material-ui v4, I get the following compile errors:

./src/index.js
Attempted import error: 'createGenerateClassName' is not exported from '@material-ui/core/styles'.

./src/index.js
Attempted import error: 'jssPreset' is not exported from '@material-ui/core/styles'.

Importing from @material-ui/styles instead, results in a successful import, but leads to another error within createGenerateClassName.js itself:

Uncaught (in promise) TypeError: Cannot read property 'Symbol(mui.nested)' of undefined

Changing the code to mirror the instructions for RTL in the v4 docs (https://material-ui.com/guides/right-to-left/) which doesn't use createGenerateClassName() at all and instead of results in a different error in css-vendor.esm.js:

Uncaught (in promise) TypeError: Cannot read property '1' of undefined

There doesn't seem to be any mention of this in the v3 -> v4 migration guide at https://material-ui.com/guides/migration-v3/

index.js

import { MuiThemeProvider, createMuiTheme, CssBaseline } from '@material-ui/core';
import { create } from 'jss';
import rtl from 'jss-rtl';
import JssProvider from 'react-jss/lib/JssProvider';
import { createGenerateClassName, jssPreset } from '@material-ui/styles';
import App from './components/App';
import chatloopTheme from './assets/stylesheets/chatloopTheme';

// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });

// Custom Material-UI class name generator.
const generateClassName = createGenerateClassName();

const theme = createMuiTheme(chatloopTheme);

// Set up redux store
const store = configureStore();

const jsx = (
  <Provider store={store}>
    <Router history={history}>
      <I18nextProvider i18n={i18n}>
        <JssProvider jss={jss} generateClassName={generateClassName}>
          <MuiThemeProvider theme={theme}>
            <CssBaseline />
            <App />
          </MuiThemeProvider>
        </JssProvider>
      </I18nextProvider>
    </Router>
  </Provider>
);

let hasRendered = false;

const renderApp = () => {
  if (!hasRendered) {
    ReactDOM.render(jsx, document.getElementById('root'));
    hasRendered = true;
  }
};

package.json

{
  "dependencies": {
    "@material-ui/core": "^4.1.1",
    "@material-ui/icons": "^4.2.0",
    "i18next": "^15.0.7",
    "react": "^16.8.3",
    "react-dom": "^16.8.3",
    "react-i18next": "^10.5.2",
    "react-jss": "^8.6.1",
    "react-scripts": "^3.0.1",   
  },
}

I'm stuck on this one and would really appreciate the material-ui community's help.

1 Answers
Related