Reputation: 320
Does anyone you know the reason to use react stateless component for huge components, with methods defined like variable, etc. I’ve recently joined to the project where used approach like this. I am confused a lot.
I guess it is better to use small components, but still
Maybe there is some logical explanation on it, like performance, etc.
simple code example:
const myComponent = ({p1, p2, p3}) => {
const buttonProps = {
className: 'button',
onClick: () => { console.log('clicked'); }
};
const getButtonName = () => 'Submit';
const getButton = () => {
return (
<button ...buttonProps>{getButtonName()}<button>
);
}
/* a lot of defined objects like above */
return (
<div>
{getButton()}
</div>
);
}
Main question is why there used methods like getButton() instead of creating MyButton component. I guess it would be easy to understand, debug, etc.
Upvotes: 0
Views: 642
Reputation: 3152
A stateful component that extends React.Component has a lot of extras. You are basically importing all the variables and functions built in to React.Component such as lifecycle functions. If you don't need them, then stateless just creates a lighter component. For example, when your component mounts, a stateful component will call componentDidMount() but a stateless doesn't even have componentDidMount().
Edit: to answer your more specific question: That function kind of is a component, a functional component, made to be reusable but inside a functional component's render function this component can't be called with the <> syntax. It's inside another component so that it's scope is limited to the parent and so that it has access to props. It's kind of opinion-based because using one kind of component over the other is just a balance of readability, reusability, and functionality.
Upvotes: 1
Reputation: 4445
A stateless component
means that is has no state
and the React
component in your example would be considered a functional component
. As for the pattern itself, it's something that could be implemented in a class component
as well - it's not something specific to only functional components
.
For example, the above code could had been written like the one below, and it would yield the same exact result:
class MyComponent extends React.Component {
render() {
const buttonProps = {
className: `button`,
onClick: () => {}
}
const getButtonName = () => `Submit`
const getButton = () => {
return (
<button {...buttonProps}>{getButtonName()}</button>
)
}
return (
<div>{getButton()}</div>
)
}
}
I don't know the context so it's hard to figure out why things are done this way - it'd be better to ask the developer responsible for choosing to write components this way to figure out the reason.
Unfortunately, or fortunately, React
is not-opinionated, and people are free to do however they please, which may result in "strange" patterns that are not always good.
The code snippet you provided creates unnecessary abstractions that are not clear at first glance - I had to figure out what getButton
does, then go to getButtonName
to see what was being rendered inside the button
element, and then I had to search for buttonProps
to figure out what props
were being passed.
If you really need a reusable function that returns a component, then why not just do it the "React
" way?
function Button({ children, ...rest }) {
const defaultProps = {
className: `button`,
onClick: () => {}
}
const props = { ...defaultProps, ...rest }
return (
<button {...props}>
{children}
</button>
)
}
Which then, going back to your example, can be used as in the following example:
// by the way, start with an uppercase when naming React components
const MyComponent = ({ p1, p2, p3 }) => {
return (
<div>
<Button>I am a button #1!</Button>
<Button
onClick={() => console.log(`HelloWorld`)}
>
I am a button #2 with a custom `onClick` handler!
</Button>
</div>
)
}
This approach is a lot better and cleaner, so just as you suggested in the comments, getButton
should written as an actual React
component.
Upvotes: 1
Reputation: 2254
In React you can either have class-based components, or function-based components (functional components).
Functional components are generally easier to test and understand, and they are lighter.
The trend in the React world is towards function-based components. This has been the case even more so in the last year or so, with the introduction of hooks (i.e. useState
, useEffect
, etc.) which allow you to have a light functional component, but with access to the things that gave class-based components their extra abilities.
There's nothing wrong per se with class-based components, but the trend is away from them, so I'm not surprised to hear you say you joined a project that does not use them.
You may be interested in one of the React Conf videos from 2018 that went into the introduction of hooks: React Conf 2018 The relevant part starts at about 11:30.
Upvotes: 1