John107
John107

Reputation: 2287

Change react component css based on props with css-modules

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

Upvotes: 2

Views: 4172

Answers (1)

Drew Reese
Drew Reese

Reputation: 202618

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.

Upvotes: 2

Related Questions