cssinjs / jss

JSS is an authoring tool for CSS which uses JavaScript as a host language.
https://cssinjs.org
MIT License
7.08k stars 399 forks source link

Dynamic values don't work when using arrow functions #1619

Open ChrisKneller opened 2 years ago

ChrisKneller commented 2 years ago

Expected behavior: I expect CSS styling to be applied based on the dynamic values of properties I pass through with arrow functions in React.

Describe the bug: Any JSS that uses arrow functions does not produce any CSS styling.

Reproduction:

Sandbox:

https://codesandbox.io/s/cool-cherry-5k2zn5?file=/src/components/Alert/Alert.js

As you can see, when the page first loads, this particular styling (red/green font and borders) does not feed through. However if we make any changes to the file then suddenly it does load. What's happening here?

From this tutorial here:

https://www.digitalocean.com/community/tutorials/how-to-style-react-components

Everything works until we get to this code:

import React from 'react';
import PropTypes from 'prop-types';
import { createUseStyles } from 'react-jss';

const colors = {
  success: '#6da06f',
  error: '#f56260',
};

const useStyles = createUseStyles({
    wrapper: {
      border: ({ type }) => `${colors[type]} solid 1px`,
      marginBottom: 15,
      padding: 15,
      position: 'relative',
      '& h2': {
        color: ({ type }) => colors[type],
        margin: [0, 0, 10, 0],
      }
    }
});

export default function Alert({ children, type, title }) {
  const classes = useStyles({ type })
  return(
    <div className={classes.wrapper}>
      <h2>{title} ({type})</h2> // extra ({type}) added by me to verify that the type was being passed through - it is
      {children}
    </div>
  )
}

The problem lies in the arrow functions, e.g.:

border: ({ type }) => `${colors[type]} solid 1px`,
...
color: ({ type }) => colors[type],

I have tried:

No matter what I do, any line that includes an arrow function gets ignored and does not generate any CSS styling.

Versions (please complete the following information):

PS C:\dev\react-training\styling-tutorial> npm list
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
styling-tutorial@0.1.0 C:\dev\react-training\styling-tutorial
├── @testing-library/jest-dom@5.16.4
├── @testing-library/react@13.3.0
├── @testing-library/user-event@13.5.0
├── nan@2.16.0 extraneous
├── react-dom@18.1.0
├── react-jss@10.9.0
├── react-scripts@2.1.3
├── react@18.1.0
└── web-vitals@2.1.4

The same seems to be happening here (though that's focussed on rtl and I don't know if that's exactly the same as what I'm using): https://github.com/cssinjs/jss/issues/1234

ChrisKneller commented 2 years ago

So it seems that this is something to do with the return of the function, because if I put

      border: function({type}) {console.log(type); return 'red solid 1px';},

then the log works correctly, but ultimately the border value doesn't appear anywhere in the resulting CSS.

ChrisKneller commented 2 years ago

Updated the original post with a sandbox. Now I really don't understand what's happening:

Sandbox:

https://codesandbox.io/s/cool-cherry-5k2zn5?file=/src/components/Alert/Alert.js

As you can see, when the page first loads, this particular styling (red/green font and borders) does not feed through. However if we make any changes to the file then suddenly it does load. What's happening here?

TwitchSeventeen commented 2 years ago

Been fighting this one for a day or two, thought I was going mad.

Mine's happening in a custom webpack setup, but I've reproduced it with straight create-react-app and no styles within a function get rendered, until you change something in the component file and then its fine.

// App.js
const useStyles = createUseStyles({
  // nada
  link: () => ({
    color: 'red',
  }),
  // fine
  link2: {
    backgroundColor: 'yellow',
  },
})

Repo is here: https://github.com/TwitchSeventeen/jss-debugging

TwitchSeventeen commented 2 years ago

@ChrisKneller and anyone else who comes across this

Looks like the issue was fixed in this PR: https://github.com/cssinjs/jss/pull/1604 but it hasn't been released yet.

Bumping react-jss to ^10.9.1-alpha.2 fixes it for me

lenryk commented 2 years ago

If you remove <React.StrictMode> from your app then you can run it with version 10.9.0.

If that's needed then upgrading react-jss to the latest alpha as @TwitchSeventeen mentioned is the only fix.

Michal41 commented 2 years ago

The issue appears only with react 18, since react 18 introduces a new root api, https://blog.saeloun.com/2021/07/15/react-18-adds-new-root-api.html.

For me helped change, to legacy Root api, in Create React applications: replace index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

reportWebVitals();

with

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
reportWebVitals();
behnammodi commented 2 years ago

@ChrisKneller version 10.9.2 is released, could you please test it