jss icon indicating copy to clipboard operation
jss copied to clipboard

Dynamic values don't work when using arrow functions

Open ChrisKneller opened this issue 3 years ago • 8 comments

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:

  • excluding the braces (to make it look more like https://cssinjs.org/react-jss/?v=v10.9.1-alpha.2#dynamic-values)
  • directly referencing colors['success'] rather than colors[type] (just in case there was a problem with type)
  • excluding type from the arrow function and just returning a string to check if I'm passing values through in the wrong way e.g. border: () => '#f56260 solid 1px',

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):

  • jss: 10.9.0
  • Browser [e.g. chrome, safari]: chrome, edge
  • OS [e.g. Windows, macOS]: Windows Feel free to add any additional versions which you may think are relevant to the bug.
PS C:\dev\react-training\styling-tutorial> npm list
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
[email protected] C:\dev\react-training\styling-tutorial
├── @testing-library/[email protected]
├── @testing-library/[email protected]
├── @testing-library/[email protected]
├── [email protected] extraneous
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

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 avatar Jun 09 '22 15:06 ChrisKneller

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 avatar Jun 10 '22 07:06 ChrisKneller

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?

ChrisKneller avatar Jun 10 '22 09:06 ChrisKneller

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 avatar Jun 10 '22 15:06 TwitchSeventeen

@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

TwitchSeventeen avatar Jun 13 '22 12:06 TwitchSeventeen

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.

lenryk avatar Jun 13 '22 15:06 lenryk

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();

Michal41 avatar Jun 28 '22 08:06 Michal41

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

behnammodi avatar Aug 05 '22 23:08 behnammodi