2

I have the following:

className={`${this.props.match.params.id}.alert`}

/* desired output = `className="style_alert__3TLGs"` */
/* instead output = `className="style.alert"` */

If I hardcode the className (eg. {style.alert}), I get the desired output. It seems as though the result is a string and is not being handled by the css-module package (perhaps because it's rendered after?), how can I change this so the className is handled by css-module and bundled as I intend?

reference docs: css-modules

8
  • I don't understand what you want to do. Why do you send an id to the class ? ${this.props.match.params.id}.alert will become something like className="48.alert". Commented Jan 14, 2020 at 15:04
  • When you use string interpolation the result will be a string, this is not unexpected. What is the value of this.props.match.params.id? Commented Jan 14, 2020 at 15:21
  • @ValentinDuboscq - Very simple, the id represents a css module, that I want to call on a reusable component, and the style changes depending on which id is in use. This is then handled by the css-modules package. Here is a very simple example: create-react-app.dev/docs/adding-a-css-modules-stylesheet Commented Jan 14, 2020 at 15:26
  • @DrewReese the value in the example above is "style", I understand it's not unexpected but my question is how can I achieve the outcome I desire with a prop that may be different each time and have it handled by the css-modules package correctly? Commented Jan 14, 2020 at 15:29
  • 2
    @DrewReese I think he wants to dynamically import different css modules based on the id. Maybe I don't quite understand but I don't think that's the right to do what you want to do. Commented Jan 14, 2020 at 15:36

1 Answer 1

2

Option 1: Import all style modules you know you'll use

Create a map of your imported "style" objects to be keyed by the ids passed in the prop. Just need to ensure all "style" objects have all the same CSS properties, like "alert", and of course, use guard pattern on the object path to the id param so no "undefined of" accesses.

import styles1 from "....";
import styles2 from "....";
...

const stylesMap = {
  style1Id: styles1,
  style2Id: styles2,
  ...
};

...

className={stylesMap[this.props.match.params.id].alert}

Pros: front load all the CSS modules you need and likely a little easier to reason about and debug

Cons: Uses more resources

Option 2: Use dynamic imports

Create an async function to "fetch" the required CSS module and use a component lifecycle function or effect hook to update the style object reference.

const loadStyle = async (...params) => {
  try {
    const styleObject = await import(...path and module name from params);
    // setState or useState setter to set style object
  } catch {
    // set a fallback style object
  }
}
...

componentDidMount() {
  // check props.match.params.id
  // gather up other CSS module path details
  // trigger dynamic CSS module load
  loadStyle(... CSS module path detials);
}
**OR**
useEffect(() => {
  // check props.match.params.id
  // gather up other CSS module path details
  // trigger dynamic CSS module load
  loadStyle(... CSS module path detials);
}, [props.match.params.id, ...any other dependencies]);

...

className={stylesMap[<this.>state.styleObject].alert}

Pros: Smaller size/less resource use.

Cons: Possibly more latency when rendering as resources are not fetched ahead of time.

Note: Also all depends on your app usage, needs, and requirements. For example, if it is a bundled app (think cordova/phonegap, electron, etc) then it is more sensible to include all the resources you need.

Sign up to request clarification or add additional context in comments.

2 Comments

Maybe using dynamic import is a best approach since you don't need to import all your files.
@ValentinDuboscq I included the idea to use dynamic imports, thanks. Feel free to point out any flaws/errors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.