when should I pass 'className' props to react component? - reactjs

Some react components pass the className props to the child component.
I haven't seen any need for passing className as a prop in my projects.
why this className props is been used ? and when should i adopt this approach?
import styled from 'styled-components'
const ReactComponent = ({ className }) => {
return <div className={className}/>
}
const StyledComponent = styled(ReactComponent)``;

It really depends on the context, but generally, the className prop is passed down from parent to child to either overwrite, or append the existing className on the child component.
This is particularly useful in the scenario when you are building reusable base components which needed to be easily extended and customised.
Given your example,
const ReactComponent = ({ className }) => {
return <div className={className}/>
}
Let's say we have a parent component which renders the child ReactComponent, and we need to customise the stylings for this instance:
return (
<div className='container'>
<ReactComponent className='is-red' />
<ReactComponent className='is-blue'/>
</div>
)
This will allow the parent to render both components, with different styles, and without the need to repeat the same code.

You generally add classes to create a style or JavaScript code snippet that effects more than one element. Here is an explanation of how to use classes.
This particular component uses StyledComponent, but it's possible that the user wanted to add a class to add extra styles on top of those for the default in specific cases.
It's also possible that the classes are used to toggle some effect in JS. I've linked examples of each case.
Without more code it's hard to say why this particular user passed down a className, but there are certainly cases where you could want to, or when you could do without passing down a className. If your code doesn't seem to require it, there's definitely no reason to add it in.

Related

How to style React component with TailwindCSS

I'm using TailwindCSS in a React Project. I'm able to style normal HTML elements by passing TailwindCSS utility classes in the className attribute but this doesn't work when I pass the utility classes inside a components className attribute like this:
<Dropdown className="hidden sm:block sm:ml-6"/>
Dropdown is a React component imported into another component.
How do I make this work?
if <Dropdown/> is your custom made component you probaly forgot to include in on the div inside your component definition,
you can rename "className" to customclass and apply it inside your component definition.
so with that your code would look like
<Dropdown customclasses="hidden sm:block sm:ml-6"/>
and your component definition,
const Dropdown = ({ customclasses, ...otherProps }) => <div className={customclasses}></div>
or if you dont want to change className you can spread the ...otherProps directly on the div
const Dropdown = ({ yourprop, yourprop , ...otherProps }) => <div {...otherProps}></div>

How is it possible to make one component stand out from other same component in React

I was creating React project and I have component which is used in several places in the project. The question is how is it possible to make one certain different from other instances of that component in terms of css styling?
For achieving that you have to accept the styles of the component as props. And each time you use the component pass the desired style to each instance.
For example
const PopupHeader = ({ title, onClose, classes }) => (
<div className={classNames(styles.head, classes.header)}>
<span className={styles.headText}>
{title}
</span>
</div>
);
Here the PopupHeader component is receiving classes as props which is actually an object of styles passed from parent component, which is used in the child component.
Hope it helps.
You can use contextAPI for sending the styles in all components
<ParentComponent>
<Style.Provider value={{ style: "background: "white .. or something" }}>
{this.props.children}
</Style.Provider>
</ParentComponent>
You can send the styles in all child components

REACT Warning Unknown props parsing to child component [duplicate]

I've built my own custom react-bootstrap Popover component:
export default class MyPopover extends Component {
// ...
render() {
return (
<Popover {...this.props} >
// ....
</Popover>
);
}
}
The component is rendered like so:
// ... my different class ...
render() {
const popoverExample = (
<MyPopover id="my-first-popover" title="My Title">
my text
</MyPopover >
);
return (
<OverlayTrigger trigger="click" placement="top" overlay={popoverExample}>
<Button>Click Me</Button>
</OverlayTrigger>
);
}
Now, I want to add custom props to MyPopover component like that:
my text
And to use the new props to set some things in the popover
for example -
<Popover {...this.props} className={this.getClassName()}>
{this.showTheRightText(this.props)}
</Popover>
but then I get this warning in the browser:
Warning: Unknown props popoverType on tag. Remove these props from the element.
Now, I guess that I can just remove the {...this.props} part and insert all the original props one by one without the custom props, but In this way I lose the "fade" effect and also it's an ugly way to handle this problem. Is there an easier way to do it?
Updated answer (React v16 and older):
As of React v16, you can pass custom DOM attributes to a React Component. The problem/warning generated is no longer relevant. More info.
Original answer (React v15):
The easiest solution here is to simply remove the extra prop before sending it to the Popover component, and there's a convenient solution for doing that.
export default class MyPopover extends Component {
// ...
render() {
let newProps = Object.assign({}, this.props); //shallow copy the props
delete newProps.popoverType; //remove the "illegal" prop from our copy.
return (
<Popover {...newProps} >
// ....
</Popover>
);
}
}
Obviously you can (and probably should) create that variable outside your render() function as well.
Basically you can send any props you want to your own component, but you'd have to "clean" it before passing it through. All react-bootstrap components are cleansed from "illegal" props before being passed as attributes to the DOM, however it doesn't handle any custom props that you may have provided, hence why you have to do your own bit of housekeeping.
React started throwing this warning as of version 15.2.0. Here's what the documentation says about this:
The unknown-prop warning will fire if you attempt to render a DOM element with a prop that is not recognized by React as a legal DOM attribute/property. You should ensure that your DOM elements do not have spurious props floating around.
[...]
To fix this, composite components should "consume" any prop that is intended for the composite component and not intended for the child component.
For further reading, check this page from the official react site.

Add custom props to a custom component

I've built my own custom react-bootstrap Popover component:
export default class MyPopover extends Component {
// ...
render() {
return (
<Popover {...this.props} >
// ....
</Popover>
);
}
}
The component is rendered like so:
// ... my different class ...
render() {
const popoverExample = (
<MyPopover id="my-first-popover" title="My Title">
my text
</MyPopover >
);
return (
<OverlayTrigger trigger="click" placement="top" overlay={popoverExample}>
<Button>Click Me</Button>
</OverlayTrigger>
);
}
Now, I want to add custom props to MyPopover component like that:
my text
And to use the new props to set some things in the popover
for example -
<Popover {...this.props} className={this.getClassName()}>
{this.showTheRightText(this.props)}
</Popover>
but then I get this warning in the browser:
Warning: Unknown props popoverType on tag. Remove these props from the element.
Now, I guess that I can just remove the {...this.props} part and insert all the original props one by one without the custom props, but In this way I lose the "fade" effect and also it's an ugly way to handle this problem. Is there an easier way to do it?
Updated answer (React v16 and older):
As of React v16, you can pass custom DOM attributes to a React Component. The problem/warning generated is no longer relevant. More info.
Original answer (React v15):
The easiest solution here is to simply remove the extra prop before sending it to the Popover component, and there's a convenient solution for doing that.
export default class MyPopover extends Component {
// ...
render() {
let newProps = Object.assign({}, this.props); //shallow copy the props
delete newProps.popoverType; //remove the "illegal" prop from our copy.
return (
<Popover {...newProps} >
// ....
</Popover>
);
}
}
Obviously you can (and probably should) create that variable outside your render() function as well.
Basically you can send any props you want to your own component, but you'd have to "clean" it before passing it through. All react-bootstrap components are cleansed from "illegal" props before being passed as attributes to the DOM, however it doesn't handle any custom props that you may have provided, hence why you have to do your own bit of housekeeping.
React started throwing this warning as of version 15.2.0. Here's what the documentation says about this:
The unknown-prop warning will fire if you attempt to render a DOM element with a prop that is not recognized by React as a legal DOM attribute/property. You should ensure that your DOM elements do not have spurious props floating around.
[...]
To fix this, composite components should "consume" any prop that is intended for the composite component and not intended for the child component.
For further reading, check this page from the official react site.

Constrain allowed children in React TypeScript

Using TypeScript in a React project is there any way to enforce some constraints on the allowed children of a component? Compile-time is preferred, but run-time could still be helpful.
In my case I have a component, call it <ClickTracker>, and it expects a single child with a callback prop onClick and it adds some extra functionality to the callback (tracking the click in an external library).
This works great as long as the child inside a <ClickTracker> does actually make use of an onClick prop (all HTML elements implement this, for example), but fails silently otherwise.
For example, this works:
<ClickTracker>
<div>Hello</div>
</ClickTracker>
But this doesn't work:
class Hello extends Component<{}, {}> {
render() {
return <div>Hello</div>
}
}
<ClickTracker>
<Hello />
</ClickTracker>
But this does work because it passes onClick to an HTML element:
class Hello extends Component<{onClick: MouseEventHandler}, {}> {
render() {
return <div onClick={this.props.onClick}>Hello</div>
}
}
<ClickTracker>
<Hello />
</ClickTracker>
As you can see I would like to have some safety around what can go inside <ClickTracker> based on the child props. Or if there's another way this could be done.
There is currently, no possible way of enforcing the children type with TypeScript.
There is more information in this issue.
Or if there's another way this could be done
Click events bubble up unless some component stopped propogation (not the default behavior for native components). So you can:
<div onClick={()=>alert('still noted')}>
<Hello />
</div>
And that div is your ClickTracker 🌹

Resources