Optimasi project khususnya di component react dapat menggunakan React.memo. penggunaan memo ini lumayan simpel seperti dibawah ini
import {memo} from "react";
const ChildComponent = memo(()=>{
return(<p>Child Component</p>)
})
const ParentComponent = ()=>{
const [count, setCount] = useState(0)
return(
<p>Example memo</p>
<p>{count}</p>
<button onClick={()=> setCount(prev => prev + 1)}>increase</p>
<ChildComponent/>
)
}
kira kira misal diclick button increase, ChildComponent bakalan dirender nggak? yups betul, jawabannya nggak dirender.
kenapa bisa begitu, karena si memo ini sendiri akan melakukan perbandingan pada props diChildComponent sedangkan pada component child tidak ada props
aman? oke lanjut ya.
import {memo} from "react";
const ChildComponent = memo((props)=>{
return(<p>Child Component {props.label}</p>)
})
const ParentComponent = ()=>{
const [count, setCount] = useState(0)
return(
<p>Example memo</p>
<p>{count}</p>
<button onClick={()=> setCount(prev => prev + 1)}>increase</p>
<ChildComponent label="name"/>
)
}
Komponen kedua ini juga masih sama ya. ChildComponent masih tidak dirender. dikarenakan si memo masih bisa melakukan perbandingan jika value pada prosps memiliki tipe data primitif
(string/number), sedangkan untuk tipe data non-primitif si memo masih akan merender ChildComponent meskipun value pada object/array itu sama.
contohnya seperti ini.
import {memo} from "react";
const ChildComponent = memo((props)=>{
return(<p>Child Component {props.label.name}</p>)
})
const ParentComponent = ()=>{
const [count, setCount] = useState(0)
return(
<p>Example memo</p>
<p>{count}</p>
<button onClick={()=> setCount(prev => prev + 1)}>increase</p>
<ChildComponent label={{id: 4, name: "hello"}}/>
)
}
Child Component akan dirender jika state pada ChildComponent berubah
untuk yang ini casenya seperti ini, misal child component memiliki state dan action untuk merubah state. sedangkan ChildComponent ini tidak dipassing data dati si ParentComponent. maka jika state didalam ChildComponent berubah makan ChildComponent akan dirender lagi.
import {memo} from "react";
const ChildComponent = memo((props)=>{
const [count, setCount] = useState(0)
return(
<p>{count}</p>
<button onClick={()=> setCount(prev => prev + 1)}>increase child</p>
<p>Child Component {props.label.name}</p>)
})
const ParentComponent = ()=>{
const [count, setCount] = useState(0)
return(
<p>Example memo</p>
<p>{count}</p>
<button onClick={()=> setCount(prev => prev + 1)}>increase</p>
<ChildComponent label={{id: 4, name: "hello"}}/>
)
}
jika user melakukan click pada button increase child makan ChildComponent akan dirender
Cara handle memo ketika dipassing sebuah object
Biasanya kalau ChildComponent dipassing sebuah data non-primitif maka akan dirender meskipun datanya sama. untuk mengatasi ini dapat menggunakkan comparing data. caranya sebagai berikut
import {memo} from "react";
const comparingMemo = (prevProps, currentProps)=>{
return JSON.stringify(prevProps) === JSON.stringify(currentProps)
}
const ChildComponent = memo((props)=>{
return(
<p>Child Component {props.label.name}</p>)
}, comparingMemo)
const ParentComponent = ()=>{
const [count, setCount] = useState(0)
return(
<p>Example memo</p>
<p>{count}</p>
<button onClick={()=> setCount(prev => prev + 1)}>increase</p>
<ChildComponent label={{id: 4, name: "hello"}}/>
)
}
dengan ini ChildComponent akan dirender jika props memiliki data non-primitif.
atau bisa juga menggunakan useMemo
import {memo, useMemo} from "react";
const ChildComponent = memo((props)=>{
return(
<p>Child Component {props.label.name}</p>)
})
const ParentComponent = ()=>{
const [count, setCount] = useState(0)
const dataObject = useMemo(()=> {id: 4, name: "hello"}, [])
return(
<p>Example memo</p>
<p>{count}</p>
<button onClick={()=> setCount(prev => prev + 1)}>increase</p>
<ChildComponent label={dataObject}/>
)
}
Handle props berupa function
belum diupdate
