React Cheat Sheet
A quick guide to save your time and effort.
As a newbie, sometimes a cheat sheet come in handy when you learn a new framework as you get used to the concepts. I’ve put together a guideline for React with useful code snippets for daily use.
Create React App
create-react-app myapp
JSX and Elements
JSX produce basic syntax for React element.
JSX can be used with valid html tags, and as expressions they can be assigned to variables or can be used conditionally or return from functions.
const element = <h1>Hello Ann</h1>;const isGreetingVisible = true;function getGreeting() {
if (isGreetingVisible) {
return element;
}
return <h1>Hello, Stranger.</h1>;
}
JSX allows to embed expressions,
In the below example, we declared a variable as name and display inside curly brackets.
const name = 'Ann Diaz';
const element = <h1>Hello, {name}</h1>;
JSX tags may contain children,
const greeting = (
// div is the parent element
<div>
{/* h1 and h2 are child elements */}
<h1>Hello</h1>
<h2>Welcome to React</h2>
</div>
);
JSX tags self close if empty:
const item = <div />;
JSX tag attributes are written in camel case:
const item = <div className="example"></div>;
Use React
- Import React and ReactDOM
import React from 'react'
import ReactDOM from 'react-dom'
2. Render JSX in to DOM element
const element = <h1>Hello World</h1>;
ReactDOM.render(element, document.getElementById("root"));
Components and Props
Components let you split UI in to reusable pieces.
- Stateless functional component
function Header() {
return <h1>Hello World</h1>;
}
2. Stateless functional component with arrow function
const Header = () => <h1>Hello World</h1>;
3. ES6 class components ( can have states)
class Header extends React.Component {
render() {
return <h1>Hello World</h1>;
}
}
- Always start component name in capital
Here’s how the components are used,
const Header = () => <h1>Hello React</h1>;ReactDOM.render(<Header />, document.getElementById("root"));
Data can be dynamically passed to components using props. Props is a single object with JSX attributes that every component receives as an argument. Props are immutable, which means they can only be read.
For example, this code renders “Hello, Ann” on the page:
function Heading(props) {
return <h1>Hello, {props.name}</h1>;
}const element = <Heading name="Ann" />;
ReactDOM.render(
element,
document.getElementById('root')
);
There is a special property called ‘children’ on props object if you want to pass elements / components to other components. It is used to display whatever you include between the opening and closing tags when invoking a component.
function Heading(props) {
return (
<div className={'Heading Heading-' + props.color}>
{props.children}
</div>
);
}//App.js
render() {
return (
<div className='container'>
<Heading color="blue">
//what is placed here is passed as props.children
</Heading>
</div>
)
}
Fragments
Fragments provides to return multiple components without adding external element to the DOM. Fragments looks like empty JSX syntax.
render() {
return (
<>
<ComponentA />
<ComponentB />
</>
);
}
Conditional Rendering
- Using if statements for rendering
function Heading(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <Greeting />;
}
return <Login />;
}
2. Using ternary operator
// Using ternary operator
<div>
{isLoggedIn ? <Greeting /> : <Login />}
</div>
3. Using logical operator
<div>
{messages.length > 0 &&
<h1>
You have messages
</h1>
}
</div>
4. Prevent component from rendering
function Modal(props) {
if (!props.isVisible) {
return null;
}
return (
<div>
Modal
</div>
);
}
Lists & Keys
We use map()
function to transform array in to list of elements.
const users = ["Ann", "Bob", "Sara"];
const usersList = users.map(user => <p>{user}</p>);
Any element that is iterated over with map() function requires a unique key to identify the element. Without keys it becomes more complicated to figure out which elements have changed, added or removed.
Key could be a string that uniquely identifies an element in array among others. Ideally, you would use IDs from your data as keys.
function App() {
const users = ["Ann", "Bob", "Sara"];
return (
<ul>
{users.map(user => <User key={user.id} name={user} />)}
</ul>
);
}
If you don’t have ids with your set of data, you can use the second parameter of .map() function to get each element’s index.Try this as the last resort as this approach is not recommended due to negative impact on performance.
function App() {
const users = ["Ann", "Bob", "Sara"];
return (
<ul>
{users.map((user, i) => <User key={i} name={user} />)}
</ul>
);
}
Handling Events
Handling events with React has slightly different syntax compared to HTML.
- Most event handlers starts with ‘handle’
- React events are named camelCase like attributes / props
- With JSX pass a function to the event handler inside curly braces
<button onClick={this.handleClick}>
Click
</button>function handleClick(e) {
e.preventDefault();
console.log('The button was clicked.');
}// Bind this to use it in the callback
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
Passing argument to event handler
In this example id is the row id and the e which represent the React event will be passed as the second argument following id argument.
<button onClick={(e) => this.deleteItem(id, e)}>Delete item</button>
Passing input value from onChange event
In below example, handleChange event returns a Synthetic Event object which contains the target inputs id, name and current value.
function handleChange(event) {
console.log(e.target.value);
} return (
<input name=”firstName” onChange={handleChange} />
);
State & Lifecycle
State is simply a pure javascript object which holds component-specific information. Unlike props which get passed from the parent component, state is local and managed within the component.
- Declare initial state in constructor
class Heading extends React.Component {
constructor(props) {
super(props);
this.state = {title: 'My heading'};
}
}
2. Use setState method to modify state. Do not modify state directly.
// Correct
this.setState({
title: 'Updated heading',
});this.state.title = 'Hello'; // Incorrect
3. setState with previous state.
this.setState((prevState, props) => {
return {count: prevState.count + 1};
});
4. Lifting state up to share state between components
Often if you need to share state between two or more siblings the solution would be lift your state up. For this, you should transfer your state to a parent component that wrap all the siblings, now from your wrapper just distribute your data down via props.
class Wrapper extends React.Component {
constructor(props) {
super(props);
this.handleInputChange = this.handleInputChange.bind(this);
this.state = {value: ''};
}
handleInputChange(value) {
this.setState({value});
}
render() {
const value = this.state.value;
return (
<Input value={value} onInputChange={this.handleInputChange} />
);
}
}
class Input extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.props.onInputChange(e.target.value);
}
render() {
const value = this.props.value;
return <input value={value} onChange={this.handleChange} />;
}
}
Component Lifecycle
There are special methods on the component class to run code when a component mount, update and unmount. Below diagram portrays a lifecycle of a component.
- constructor : called only once in whole lifecycle, used to setup the initial state of the component or to bind event handler method.
constructor(props) {
super(props);
this.state = {qty: this.props.qty}
this.clickHandling = this.clickHandling.bind(this);
}
2. getDerivedStateFromProps: invoked before calling render method and is expected to return an object to update the state, or null to update nothing. This method is used when state is dependent on props and to sync state with props change.
static getDerivedStateFromProps(props, state) {
if(props.qty !== state.qty) {
return {qty: props.qty}
}
return null;
}
3. render: This is the only required method in lifecycle. This get invoked whenever state or props change and re-renders the HTML with new changes.
render() {
return(
<div>
<h2>Cart Items ({this.state.qty})</h2>
</div>
)
}
4. componentDidMount: This is invoked immediately after the component is mounted. This is a good place to make API calls.
constructor(props) {
super(props);
this.state = {news: []};
}componentDidMount() {
console.log('Execute this method after component render');
fetch('https://example.com/news')
.then(response => response.json())
.then(data => this.setState({ news: data.news }));
.catch(error => console.log(error));
}
5. shouldComponentUpdate: This method returns a boolean value which specifies React whether to re-render or skip rendering component altogether when component’s state or props are updated. By default this method returns true.
shouldComponentUpdate(nextProps, nextState) {
if(this.props.qty !== nextProps.qty) {
return true; // component should update
}
return false;
}
6. getSnapshotBeforeUpdate: This method is called before the most recently rendered output is committed to DOM. This method has access to both previous and current props and also state. If this method return any value the same is available in componentDidUpdate method as third parameter. This method is useful in tracking state between current DOM and updated DOM. (Eg. scroll position, text selection )
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// Are we adding new items to the list?
// Capture the scroll position so we can adjust scroll later.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// If we have a snapshot value, we've just added new items.
// Adjust scroll so these new items don't push the old ones out of view.
// (snapshot here is the value returned from getSnapshotBeforeUpdate)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
7. componentDidUpdate: This method is invoked immediately after component is updated ( when props or state changes). This method is not called for the initial render. This is a good place to re-load third party libraries and to compare previous prop/state values with current prop /state values.
componentDidUpdate(prevProps, prevState){
if(this.props.qty !== prevProps.qty){
console.log('component updated');
}
}
8.componentWillUnmount: This method is immediately executed when the component is unmounted or removed from DOM. This method is used to do cleanup related to the component. (Eg. clear user sessions, invalidate timers, cancel network requests)
componentWillUnmount() {
console.log('component is unmounted and destroyed');
this.resetLocalStorage();
this.clearSession();
}
Forms
In react we have two types of inputs. There are uncontrolled inputs which are like traditional HTML form inputs which we use ref to get form values.
class Form extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.input = React.createRef();
}
handleSubmit(event) {
console.log(this.input.current.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Controlled Inputs
In controlled inputs when form value changes, the component that renders the form saves the value in its state. As in below example, each state mutation has a handler function.
constructor () {
this.state = {
username: ''
}
}
changeHandler = event => {
this.setState({
username: event.target.value
});
}
render () {
return (
<form>
<input type="username"
name="username"
value={this.state.username}
onChange={this.changeHandler}
/>
</form>
);
}
<textarea> tag works similar to input tag using value attribute.
<textarea value={this.state.value} onChange={this.handleChange} />
Unlike in HTML <select> tag use a value and not a selected attribute.
<select value={this.state.value} onChange={this.handleChange}>
<option value="a">Option A</option>
<option value="b">Option B</option>
</select>
You can pass an array to value attribute to have multiple options.
<select multiple={true} value={['a', 'b']}>
Handling multiple form inputs
When there are multiple form inputs we can handle it by modifying the changeHandler method. Here we add name attribute to each input element so that handler can update state dynamically. The name attribute should be same as the name of state as declared in the constructor.
handleInputChange(e) {
const target = e.target;
const value = target.value;
const name = target.name;
this.setState({
formControls: {
[name]: value
}
});
}
render() {
return (
<form>
<input name="firstName" onChange={this.handleInputChange} />
<input name="lastName" onChange={this.handleInputChange} />
</form>
);
}
So this article sums up the main concepts of React with useful code snippets for easy reference. Hope you find this useful.
☕️ Thanks for reading.