📖 History of "Stop unnecessary re-rendering component in React !!"
Tags: react, javascript, frontend
Published: 2022-05-07 12:00:20

once upon time...
## 💎 Generation of class component

### 🚩 Pure component()
Compare new and old props/state, if there is difference between them, component renders

***compare?? but how to compare them??***

<< the case of rendering in React >>
> 1. state changes
> 2. parent component renders
> 3. props changes
> 4. shouldcomponentUpdate function returns true (I'll explain about it later)
> 5. forceUpdate

for numbers 1 and 2, React decides whether to render through [shallow compare](https://ja.reactjs.org/docs/shallow-compare.html)

***What is shallow compare?***

At first, we need to get what is **reference**
▼ [from this website](https://blog.penjee.com/passing-by-value-vs-by-reference-java-graphical/)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8qadygmii8f6c42gknr.gif)
 
1. pass by reference (shallow copy)
  If you pour coffee in copied cup, original cup is also filled with it (because both datas are in same memory allocation space)

2. pass by value (deep copy)
  If you pour coffee in copied cup, original cup is still empty

in Javascript, primitive data type (String, Number, Bigint, Boolean, Undefined, Symbol) is pass by value, and Object, Array is pass by reference
 
honestly comparing with primitive data type is not so difficult, but we need to care about comparing with Object

**the case of object reference is the same**
```javascript
import shallowCompare from 'react-addons-shallow-compare';

const a = { country: "poland", country2: "japan" }
const b = a

console.log(shallowEqual(a, b))
// true
```

**the case of object reference is different**
1. not nested object
```javascript
import shallowCompare from 'react-addons-shallow-compare';

const a = { country: "poland", country2: "japan" }
const b = { country: "poland", country2: "japan" }

console.log(shallowEqual(a, b))
// true
```

2. nested object
```javascript
import shallowCompare from 'react-addons-shallow-compare';

const a = {
  country: "poland",
  coountry2: {
    city1: "tokyo",
    city2: "osaka"
  }
}

const b = {
  country: "poland", // country is primitive type, scalar data is the same -> true
  country2: { // country2 is object, so reference is different -> false
    city1: "tokyo",
    city2: "osaka"
  }
}

console.log(shallowEqual(a, b))
// ⭐ false
```

### 🚩 shouldComponentUpdate()
> 👦 so it is ok all components are pure component, isn't it?
> 👩‍💻 no, because cost of comparing old and new state/props is high
> 👦 what should I do then?
> 👩‍💻 just decide comparing condition by yourself via "shouldComponentUpdate()"

actually PureComponent is like component which is implemented by someone(would be someone in facebook company) through shouldComponentUpdate()

```javascript
// something like that
class PureComponent extends React.Component {
	shouldComponentUpdate(nextProps, nextState) {
		return !(shallowEqual(this.props, nextProps) && shallowEqual(this.state, nextState));
	}
	…
}
```
---

## 💎 Functional Component generation
2022 we are in this generation

### 🚩 React.memo
it is like PureComponent() + shouldComponentUpdate()

```javascript
// if new props changes, this component will be rendered
const Button = React.memo(props => {
	return <div>{props.value}</div>
})
```

```javascript
// if you put second argument, it is like shouldComponentUpdate()
const Button = React.memo(
	props => {
		return <div>{props.value}</div>
	},
	(nextProps, prevProps) => {
		return nextProps.value === prevProps.value
	}
)
```

### 🚩 useMemo
> 👦 what is useMemo? it is the same of React.memo?
> 👩‍💻 no, similar though. React.memo is added by React version16.6, and then React hook is added by version 16.8, useMemo as well.
> 👦 aha
> 👩‍💻 useMemo renders only when props changes because it remembers calculation result

```javascript
// when only "products props" changes, this component renders
const Component: React.FC = ({ products }) => {
	const soldoutProducts = React.useMemo(() => products.filter(x => x.isSoldout === true), [products])
}
```

### 🚩 useCallback
When parent component passes props of function to child component, new function (actually function is just one of object) is made.
Because of it child component recognize this new function is different from old one, then re-renders sadly.

↓ conversation between child/parent component
> 👨 Parent「re-renderiiingggg!! And now I recreated function that I have !!」
> 👼 Child「Mom!! Give me your function as props!!」
> 👨 Parent「ok I give you my function!」
> 👼 Child「well now I need to confirm this object’s memory address is the same as object that I got before …. Hmmm different address, I also re-rendering!!!」

to prevent this unnecessary re-rendering, should use useCallback