Reputation: 748
Sorry if the question is stupid, I'm new to React.
Let's say I have such a component:
import React from 'react';
import Container from '../Miscellaneous/Container/Container'
import MaskedImgBlock from '../MaskedImgBlock/MaskedImgBlock'
import HeaderImg from 'assets/img/header/header-img.jpg'
import styles from './Header.module.scss'
const header = (props) => {
return(
<header className={styles.mainHeader}>
<Container>
<div className={styles.mainHeader_inner}>
... {/* some other code here */}
<MaskedImgBlock
src={HeaderImg}
alt="Team members photo"/>
</div>
</Container>
</header>
)
};
export default header;
And I have in it a reusable MaskedImgBlock
component:
import React from 'react';
import styles from './MaskedImgBlock.module.scss'
const maskedImgBlock = ({ src, alt }) => {
return (
<div className={styles.imgBlock}>
<div className={styles.imgBlock_clipped}>
<img className={styles.imgBlock_img}
src={src}
alt={alt} />
</div>
</div>
)};
export default maskedImgBlock;
This MaskedImgBlock
component I want to use inside multiple components in my app, and it must keep its structure and most of styles, but some styles of it's inner elements must be changed according to the component's position.
For example, when this component is inside Header
component, one of its inner divs must have a green background-color, and if it's inside a footer component, other inner div must be of yellow background color.
How can I achieve this effect in the most nice way?
Upvotes: 1
Views: 2212
Reputation: 4445
Similarly to what's done in the Material-UI
framework for React
, you could introduce a new prop
for the MaskedImgBlock
component, like in the following example:
const MaskedImgBlock = ({
src,
alt,
classes = {}
}) => {
const {
root = '',
imgWrapper = '',
img = '',
} = classes
return (
<div className={`${styles.imgBlock} ${root}`}
<div className={`${styles.imgBlock_clipped} ${imgWrapper}`>
<img className={`${styles.imgBlock_img} ${img}`}></igm>
</div>
</div>
)
}
Then, assuming you want to style root
and img
, you could do the following:
const Header = (props) => {
return (
<header>
<Container>
<div>
<MaskedImgBlock
src={HeaderImg}
alt="Team members photo"
classes={{
root: styles.mainHeader_maskedImgBlock_root,
img: styles.mainHeader_maskedImgBlock_img
}}
/>
</div>
</Container>
</header>
)
}
Or, if you just want the default styling, you don't pass any extra props
to your component:
const Header = (props) => {
return (
<header>
<Container>
<div>
<MaskedImgBlock
src={HeaderImg}
alt="Team members photo"
/>
</div>
</Container>
</header>
)
}
This way, you only pass the classes that you want and everything else will default to existing styles.
Upvotes: 3
Reputation: 537
How do you define styles for MaskedImgBlock
classes in parent components?
You use css modules in MaskedImgBlock
, so its class names will be generated according with your style/css/or*other-loader config.
If you need couple different representation - it better to add some prop to MaskedImgBlock
component and path it from parent like
import React from 'react';
import Container from '../Miscellaneous/Container/Container'
import MaskedImgBlock from '../MaskedImgBlock/MaskedImgBlock'
import HeaderImg from 'assets/img/header/header-img.jpg'
import styles from './Header.module.scss'
const header = (props) => {
return(
<header className={styles.mainHeader}>
<Container>
<div className={styles.mainHeader_inner}>
... {/* some other code here */}
<MaskedImgBlock
theme={'green'}
src={HeaderImg}
alt="Team members photo"/>
</div>
</Container>
</header>
)
};
export default header;
If you want to customize your MaskedImgBlock
component with many styles from different parent compoments - the best approach is adding className (or etc.) prop to your MaskedImgBlock
component, where you can pass class name from parent component (like your Header component).
import React from 'react';
import Container from '../Miscellaneous/Container/Container'
import MaskedImgBlock from '../MaskedImgBlock/MaskedImgBlock'
import HeaderImg from 'assets/img/header/header-img.jpg'
import styles from './Header.module.scss'
const header = (props) => {
return(
<header className={styles.mainHeader}>
<Container>
<div className={styles.mainHeader_inner}>
... {/* some other code here */}
<MaskedImgBlock
className={styles.maskedImg}
src={HeaderImg}
alt="Team members photo"/>
</div>
</Container>
</header>
)
};
export default header;
And new MaskedImgBlock
import React from 'react';
import styles from './MaskedImgBlock.module.scss'
const maskedImgBlock = ({ src, alt, className = '' }) => {
return (
<div className={`${styles.imgBlock} ${className}`}>
<div className={styles.imgBlock_clipped}>
<img className={styles.imgBlock_img}
src={src}
alt={alt} />
</div>
</div>
)};
export default maskedImgBlock;
Upvotes: 1