Some ES6+ features used in React development
The newest versions of JavaScript, ES2015 (ES6), ES2016 (ES7), ES2017 and beyond have many features that can be used today via Babel. Here are a few features I've used in React development.
Arrow functions (ES2015)¶
Arrow functions provide a shorthand syntax for defining functions. They also do not bind a this
context so this
from the lexical scope is used instead. If no curly braces are used, the value after the arrow is returned. There are other subtleties (e.g. hoisting and naming) associated with function expressions vs. function declarations. I like using arrow functions in blog posts for brevity, but I haven't decided if I like them in all circumstances yet. More information: Arrow Functions - YDKJS: ES6 & Beyond, Arrow functions - Exploring ES6, and Arrow This | getiblog for an explanation about this
.
Here is a stateless React component defined using an arrow function:
const App = () => ( <div> <PageBehindModals /> <ChainedModals modalList={[ModalName, ModalPhone]} /> </div> );
Without arrow functions, it could be written as:
function App() { return ( <div> <PageBehindModals /> <ChainedModals modalList={[ModalName, ModalPhone]} /> </div> ); }
Destructuring (ES2015)¶
The shorthand destructuring shown assigns properties of an object to variables of the same name. There is also a longhand syntax that allows you to assign to variables of different names. Destructuring works with nested objects, with arrays, and can be used in variable declarations, function return values and function arguments. More information: Destructuring - YDKJS: ES6 & Beyond
Here is an example destructuring the objects this.props
and this.state
:
class ChainedModals extends Component { render() { const { modalList } = this.props; const { currIndex, showModal } = this.state; // .. } }
Without destructuring, it could be written as:
class ChainedModals extends Component { render() { const modalList = this.props.modalList; const currIndex = this.state.currIndex; const showModal = this.state.showModal; // .. } }
Destructuring function arguments (ES2015)¶
Destructuring can be applied to function arguments that are objects or arrays. More information: Destructuring Parameters - YDKJS: ES6 & Beyond
This function expects a single object as an argument and it is destructured into onClickNext
and step
.
function ModalName({ onClickNext, step }) { return ( <div> <h1>Step {step} - Name</h1> <Button onClick={onClickNext}>Next</Button> </div> ); }
Without destructuring, it could be written as:
function ModalName(props) { var onClickNext = props.onClickNext; var step = props.step; return ( <div> <h1>Step {step} - Name</h1> <Button onClick={onClickNext}>Next</Button> </div> ); }
Nested destructuring (ES2015)¶
Destructuring also applies to objects nested in objects. More information: Nested Destructuring - YDKJS: ES6 & Beyond
Here is an example destructuring the nested props
object:
function setIndexFromRoute(props) { const { modalList, location: { pathname } } = props; // .. }
Without destructuring, it could be written as:
function setIndexFromRoute(props) { const modalList = props.modalList; const pathname = props.location.pathname; // .. }
Object rest/spread operator (ES2018)¶
The ...
rest operator gathers the rest of the items in the props object argument and puts them in the variable rest
. The ...
in the JSX is actually JSX syntax for spreading the props in the the rest
object into individual props. More information: Object Rest/Spread Properties ECMAScript proposal, Objects Properties and ... - YDKJS: ES6 & Beyond, Using Object Spread Operator - Redux documentation, and JSX Spread Attributes - React documentation.
The object rest/spread operator is currently at stage 3 in the approval process so the earliest release would be ES2018. Note there is a rest/spread operator for arrays in ES2015.
function ModalName({ onClick, ...rest }) { return ( <Modal {...rest}> <Button onClick={onClick}>Next</Button> </Modal> ); }
If only onClick
, show
, and backdrop
props are passed to ModalName
, it could be written like this. Using the rest and spread operators are useful when the properties are variable or unknown.
function ModalName(props) { var onClick = props.onClick; var show = props.show; var backdrop = props.backdrop; return ( <Modal show={show} backdrop={backdrop}> <Button onClick={onClick}>Next</Button> </Modal> ); }
Object spread example
Here is an example using the object spread operator to merge 2 objects into a new object:
const initialState = { modalList: ["/name", "/phone", "/done"], currIndex: null, formData: { name: "Servur", phone: null, }, }; function handleRouteChange(state = initialState, pathname) { const index = state.modalList.findIndex(path => path === pathname); return { ...state, currIndex: index }; }
Here is how it could be done using Object.assign
(ES2015):
function handleRouteChange(state = initialState, pathname) { const index = state.modalList.findIndex(path => path === pathname); return Object.assign({}, state, { currIndex: index }); }
Doing it using ES5 is much harder.
Concise properties (ES2015)¶
See Concise Properties - YDKJS: ES6 & Beyond
Here is an example using ES2105 concise properties:
const a = 1; const b = 2; const c = { a, b };
It could be written in ES5 without concise properties as:
var a = 1; var b = 2; var c = { a: a, b: b };
Array#includes
(ES2016)¶
See Array#includes - YDKJS: ES6 & Beyond
Here is an example testing whether a value is included in an array using ES2016 Array#includes
:
const selectedRows = [1, 2, 3]; const isSelected = selectedRows.includes(rowId);
Here is how it could be written using ES5:
var selectedRows = [1, 2, 3]; var isSelected = selectedRows.indexOf(rowId) >= 0;
Template literals (ES2015)¶
Template literals provide support for string interpolation. Variables and arbitrary expressions may be substituted into the string. More information: Template Literals - YDKJS: ES6 & Beyond
Here is an example using template literals:
const host = "api.github.com"; const url = `https://${host}/search/code`;
Here is how it could be written without template literals in ES5:
var host = "api.github.com"; var url = "https://" + host + "/search/code";
See also¶
Related posts
- How to use ast-grep with GraphQL — posted 2024-09-24
- Next.js App Router (RSC) projects w/ open source code — posted 2024-07-30
- Next.js Relay GraphQL Pokemon example — posted 2024-05-22
- Example Node.js Passport.js SAML app using OneLogin — posted 2024-05-10
- Aphrodite to CSS Modules codemod — posted 2022-12-09
- Simple codemod example with jscodeshift — posted 2021-05-03
Comments
Very interesting, I knew about the rest operator but the destructuring is quite new and challenging. Thanks a lot for the links to YDKJS, now I feel like a beginner in JS after learning that many things there and only read about 10% of the chapter 2.
disqus:3074019289
Thanks for your comment. I agree there is a lot to learn in YDKJS.
disqus:3074969867
I love this man. Good job
disqus:3153739144
Really great explanation of the key advantages, I think taking advantage of destructuring increases a lot code readability. Thanks for sharing it
disqus:3428341241