我們踏進 React 的世界也將近 20 天了,對於 React 渲染的機制應該也略知一二了...你說你不懂,那就讓我來解釋一下吧,我們一樣做出了 Parent.js
和 Child.js
Component,並在 App.js
使用 useState 做一個簡單的計數器,畫面會像是這樣
// App.js
import { useState } from 'react';
import { Parent } from './Parent';
import './index.css';
function App() {
const [count, setCount] = useState(0)
console.log("APP 組建 渲染");
const clickHandler = () => {
setCount(perv => perv + 1)
}
return (
<div className='border'>
<div>
我是在 APP.js 的 count :{ count }
</div>
<button onClick={clickHandler}>點我加一</button>
<Parent item={"傳下來的東西"} />
</div>
);
}
export default App;
// Parent.js
import './index.css'
import { Child } from "./Child"
const Parent = ({ item }) => {
console.log("我是Parent.js 為啥要渲染我啊");
return (
<div className='parent'>
我是Parent.js
<span className='item'>{ item }</span>
<Child item={item} />
</div>
)
}
export { Parent }
// Child.js
import './index.css'
const Child = ({ item }) => {
console.log("我是Child.js 為啥要渲染我啊");
return (
<div className='child'>
我是Child.js
<span className='item'>{ item }</span>
</div>
)
}
export { Child }
但是這時悲劇就發生了,每當我在最上層的 App.js
點擊button
讓他去執行,setCount
,這時大家也都知道,這個行為會呼叫,React 重新渲染 App.js
這個組件,然後這時,發現了 App.js
這個組件中,還有其他子組件,這時 react 也會去渲染這個組件,直到,沒有組件可以渲染為止,所以才會造成畫面上的這個效果
但是大家都知道老套路了,React 本人也發現了這個問題,所以 React.memo就來拯救世界了
知道這項工具知道,那我們該怎麼使用呢?
讓我們來試試看吧,其實很簡單
先讓我們思考一下,現在 App.js
會因為 useState 的狀態改變而渲染,這點沒錯
但是我們的 Parent.js
和 Child.js
不需要重新渲染,為什麼?
因為第一點 因為傳下來的 props
沒有改變,在我們的例子中是一個字串,"傳下來的東西"
再來就是,如果每次父層渲染都要影響子層的話,而且子層的狀態沒有改變,那為什麼要跟這渲染。
思考之後,我們就可以在我們不需要被渲染的地方加上今天的主角 memo
在 Parent.js
和 Child.js
加上這些
讓 memo
將我們的 function 包起來
// Parent.js
import './index.css'
import { Child } from "./Child"
import { memo } from 'react';
const Parent = memo(({ item }) => {
console.log("我是Parent.js 為啥要渲染我啊");
return (
<div className='parent'>
我是Parent.js
<span className='item'>{ item }</span>
<Child item={item} />
</div>
)
})
export { Parent }
// Child.js
import './index.css'
import { memo } from 'react';
const Child = memo(({ item }) => {
console.log("我是Child.js 為啥要渲染我啊");
return (
<div className='child'>
我是Child.js
<span className='item'>{ item }</span>
</div>
)
})
// 注意你也可以這樣使用 memo
// const MemoChild = memo(Child)
// 但是注意要引出的時候要用對人 export { Child, MemoChild }
// 引入時也是一樣
export { Child }
讓我們來看看下效果吧
成功做出我們要的效果了~
其實這兩個東西是一樣的,只是有些人會習慣在 import
的時候,把 React 引入像是這樣
import React from 'react';
這樣你一樣可以使用 React.useState(),React.memo
但是本人我比較喜歡像是這樣,只引入自己需要的 function
import { useState, memo } from 'react';
這樣也可以很清楚知道,這個組件使用了什麼,也可以打比較少字~
今天介紹了看起來所向無敵的 memo
,但是他還是有弱點的喔!
我怎麼會這樣說呢,明天你就知道了,謝謝大家收看