menu

React

A community of developers, designers and others who love React.js. ⚛️

Channels
Team

How do you write your functional components?

May 14, 2018 at 9:08am

How do you write your functional components?

May 14, 2018 at 9:08am (Edited 1 year ago)
Hey guys!
A quick question regarding functional components. I keep seeing two common patterns when it comes to creating a functional component:
function Card({ placeholder, definition }) {
return (
<StyledCard w={1} mb={2}>
<StyledInput placeholder={placeholder} value={definition} type="text" />
</StyledCard>
);
}
export default Card;
const Card = props => {
return (
<StyledCard w={1} mb={2}>
<StyledInput
placeholder={props.placeholder}
value={props.definition}
type="text"
/>
</StyledCard>
);
};
export default Card;
Code style aside, what are the nuances of both patterns? How do you prefer to write your functional components?
Thanks for your input!

May 14, 2018 at 9:17am
2nd version + destructure pros + `no return`, like:
const Card = ({ placeholder, definition }) => (
<StyledCard w={1} mb={2}>
<StyledInput
placeholder={placeholder}
value={definition}
type="text"
/>
</StyledCard>
);
export default Card;
like-fill
20
  • reply
  • like
Arrow functions can tempt you to export them directly
export default props => <h1>Hello World</h1>;
which is slightly bad for debugging as it isn't named anymore. Also, if you wish to add `propTypes` to it, it becomes bit verbose as you need to convert it into a named arrow function.
So unless you're doing this, either of the options are fine. I personally like to just use `class extends PureComponent` as my default.
like-fill
4
  • reply
  • like
Neat, thanks guys :)
  • reply
  • like
I use Flow, so typing in pure functions is no problem, but I agree that it's better to not directly export default, because you loose the names. I usually prefer destructuring in the header, because it's immediately clear what the function will be receiving, the only time I don't do that is if I need access to the whole props to pass along to a sub-component `{...props}`.
like-fill
1
  • reply
  • like
(PS: My first puerile response when I read your question title was: "With my keyboard" :))
  • reply
  • like
2nd version + destructure pros + `no return`, like:
const Card = ({ placeholder, definition }) => (
<StyledCard w={1} mb={2}>
<StyledInput
placeholder={placeholder}
value={definition}
type="text"
/>
</StyledCard>
);
export default Card;
The return isnt required since its an arrow function, correct?
  • reply
  • like
Yeah I was just going to say. Eslint always complains when I do that. One neat thing I learnt recently is that you can do
const card = ({title, content}) =>
console.log(title) || <h1>{title}</h1><p>{content}</p>
if I need a quick console log of something, without having to turn it back into a { return()} structure.
like-fill
8
  • reply
  • like
haha! Yeah I'd like to dig into Flow once I get better with React and Redux. Im afraid Flow will throw me over the edge.
  • reply
  • like
One thing that has sometimes caused bugs is when I forgot the {} though. So I do
  • reply
  • like
Right, arrow fns return by default if you ommit curly braces https://jsfiddle.net/fwhg778m/
  • reply
  • like
const Card = (title) => <h1>{title}</h1>
and React says "Expected component or string or null"
  • reply
  • like
To me it would have made so much sense to have implicit return within curly brackets as well, like a lot of other languages, but that's JS :)
  • reply
  • like
With neovim it immediately highlights when I make a Flow mistake, and it's awesome for productivity. Some things are hard to type, and I don't aim for 100% at all, but especially for typing between files and modules, to remember that a certain utility function takes a number and a string, not the other way around, or it requires an object with these keys... Then later when you change the utility function, it immediately tells you all the places you need to update etc.
like-fill
1
  • reply
  • like
We have a monorepo with a main app and lot's of plugins, and we use this shared file to coordinate types between all the different packages. https://github.com/chili-epfl/FROG/blob/develop/frog-utils/src/types.js
  • reply
  • like
I use Flow, so typing in pure functions is no problem, but I agree that it's better to not directly export default, because you loose the names. I usually prefer destructuring in the header, because it's immediately clear what the function will be receiving, the only time I don't do that is if I need access to the whole props to pass along to a sub-component `{...props}`.
Do you have a snippet of this anywhere? I just curious what it looks like syntactically.
  • reply
  • like
Good to know! I'm Neovim user as well, so that's great.
  • reply
  • like
Do you have a snippet of this anywhere? I just curious what it looks like syntactically.
Not sure exactly what you are referring to?
  • reply
  • like
Just how a functional component would look like with Flow, as you described.
  • reply
  • like
https://youtu.be/Df7fC-SdT7I - I import Flow definitions from that file I linked above (in a different NPM package). Then I show that the exported interface from this plugin has to have the right fields, they have to be at the right type etc. Note that this is all synchronous - I never save the file while I'm editing.
  • reply
  • like
Excellent, thank you very much!
  • reply
  • like
Honestly I am thinking more and more to not write any funtional component anymore. They are very unperformant unable to be optimized i have to refactor code if i never need state or lifecycle etc et. However if had to write one i prefer named function amd destructure the props in the top. const { foo, bar } = props and use a return. That helps the most if i need to refactor inyp class
  • reply
  • like
Honestly I am thinking more and more to not write any funtional component anymore. They are very unperformant unable to be optimized i have to refactor code if i never need state or lifecycle etc et. However if had to write one i prefer named function amd destructure the props in the top. const { foo, bar } = props and use a return. That helps the most if i need to refactor inyp class
  • reply
  • like
Never heard that they are unperformant, and I think in the future React will optimize specifically for them.
  • reply
  • like
Well they are. Just try yourself the function component rewrites all its content on the dom instead of diffing properly. But to me the real deal breaker is the cognitive effort of converting to class again (whichbis often)
  • reply
  • like
And you get the additionaal benefit of one less choise TM..
  • reply
  • like
Show more messages