Samra
Samra

Reputation: 2015

setting style values dynamically - react

I need a way to toggle 'flex' to 'none' and vice versa for the following:

const UpdateSampleStyle = makeStyles((theme) => ({
    gridcontainer: {
    display: 'none', //props => props.show,
    justifyContent:'center', 
    marginTop:'5px'
  },
}));


 function UpdateFieldObservations({formdata, handleChangeParent}){
 const show = 'flex';
 const classes = UpdateSampleStyle(show);
const [displaySettings, setDisplaySettings] = useState({
  tradeWaterGrabSample: {display:'flex', justifyContent:'center', marginTop:'5px'},
  tradeWaterCompositeProgram: {display:'flex', justifyContent:'center', marginTop:'5px'},
  soilVapourGrabSample: {display:'flex', justifyContent:'center', marginTop:'5px'},
  soilVapourInsituMeter: {display:'flex', justifyContent:'center', marginTop:'5px'},
  stackEmissionGrabSample: {display:'flex', justifyContent:'center', marginTop:'5px'},
  stackEmissionInsituMeter: {display:'flex', justifyContent:'center', marginTop:'5px'},
  dustDeposition: {display:'none', justifyContent:'center', marginTop:'5px'}
});

}

It is used as follows:

<Grid container spacing={3} style={displaySettings.tradeWaterGrabSample}>
</Grid>
<Grid container spacing={3} style={displaySettings.tradeWaterCompositeProgram}>
</Grid>
<Grid container spacing={3} style={displaySettings.soilVapourGrabSample}>
</Grid>

and so on..

Update: So there were tiny mistakes in my code after I implemented the solution here...that can go unnoticed, adding here for anyone facing the same:

 const classes = UpdateSampleStyle(show);

changed to

 const classes = UpdateSampleStyle({show});

classname changed to className

Upvotes: 0

Views: 2965

Answers (2)

Tuhin
Tuhin

Reputation: 3373

First of all, this is not the right approach while applying styles.

Solution 1:

If you are using plain css, you can keep your styles in separate css files.

For example,

.tradeWaterGrabSample {
 // your styles
}
.hidden {
  display: none;
}

Later, in JSX you can put the css classes: For example

<Grid container spacing={3} className=`tradeWaterGrabSample ${yourCondition ? 'hidden' : ''}`>
</Grid>

Solution 2:

You can use classnames / clsx npm library for applying multiple styles: https://www.npmjs.com/package/clsx

https://www.npmjs.com/package/classnames

in this case you can easily apply multiple classes based on condition: Eg:

import classNames from 'classnames';
...
<Grid container spacing={3} className={classNames('tradeWaterGrabSample' , {'hidden': true}> // replace true by your condition
</Grid>

Solution 3:

By seeing Grid container I am assuming you are using material-ui / MUI.

If your using MUI (Aka v5), then you can use sx prop For example,

<Grid container spacing={3} sx={{
 display: condition ? 'none' : 'flex'
}}
justifyContent="center"
mt="5px"
>
</Grid>

For reference:

https://mui.com/system/the-sx-prop

https://mui.com/guides/interoperability/

If your using Material ui (Aka v4), then "sx" prop does not work. you can use makeStyles / withStyles instead.

References:

https://v4.mui.com/styles/api/

https://v4.mui.com/guides/interoperability/

As you confirmed about material-ui v4

You can use following:

const useStyles = makeStyles({
  gridContainer: {
   marginTop: "5px"
  },
  hidden: {
    display: "none"
  },
});

use following inside component:

const classes = useStyles(props);

<Grid 
  container 
  spacing={3} 
  justifyContent="center"
  className={classNames(classes.gridContainer, { [classes.hidden]: true } )} // replace true by your condition
>
</Grid>

https://v4.mui.com/styles/api/#makestyles-styles-options-hook

Based on your comment, to use component's props, you can follow this example: https://v4.mui.com/styles/basics/#adapting-based-on-props

Upvotes: 2

Edward
Edward

Reputation: 435

I think there's multiple ways to do it though the way I would do it would be to add a reference to the styled component.

import { useRef } from "react";

//declare component
const ref1 = useRef(null);

return(
<Grid container spacing={3} style={displaySettings.tradeWaterGrabSample} ref={ref1}>
</Grid>
);

To change the display from flex to none you would just have to do:

ref1.current.style.display = none OR ref1.current.style.display = flex

Upvotes: 0

Related Questions