一文帶你了解React中的函數(shù)組件
1. 創(chuàng)建方式
// 寫(xiě)法一 const Hello = (props) => { return <div>{props.message}</div> } // 寫(xiě)法二 const Hello = props => <div>{props.message}</div> // 寫(xiě)法三 function Hello(props) { return <div>{props.message}</div> }
2. 函數(shù)組件代替類組件
面臨的問(wèn)題
- 函數(shù)組件沒(méi)有state => React v16.8.0推出Hooks API,其中的一個(gè)API叫做useState可以解決問(wèn)題
- 函數(shù)組件沒(méi)有生命周期 => React v16.8.0推出Hooks API,其中的一個(gè)API叫做useEffect可以解決問(wèn)題
我們對(duì)比一下兩種組件實(shí)現(xiàn) n + 1 的例子
類組件
class App extends React.Component { constructor(props) { super(props); this.state = { n: 0 } } addNum = () => { this.setState({n: this.state.n + 1}) } render() { return ( <div className='App'> <span>n:{this.state.n}</span> <button onClick={this.addNum}>n+1</button> </div> ) } }
函數(shù)組件
const App = props => { const [n,setN] = React.useState(0) function addNum(){ setN(n + 1) } return ( <div className='App'> {n} <button onClick={addNum}>+1</button> </div> ) }
相比之下函數(shù)組件更為簡(jiǎn)潔一些
使用 useEffect 解決生命周期問(wèn)題
1.模擬 componentDidMount 首次渲染
useEffect(() => { // 模擬componentDidMount 首次渲染 console.log('use effect') },[]) // 空數(shù)組必須寫(xiě)
2.模擬 componentDidUpdate
const [n, setN] = React.useState(0) useEffect(() => { // 模擬 componentDidUpdate console.log('n 變化了') },[n]) // 數(shù)組里面可以寫(xiě)多個(gè)參數(shù)表示監(jiān)聽(tīng)多個(gè)變量 useEffect(() => { // 模擬 componentDidUpdate console.log('任意屬性變更了') }) // 不寫(xiě)數(shù)組表示監(jiān)聽(tīng)所有 useState 的變量 // 但是這樣在第一次渲染時(shí)也會(huì)觸發(fā)函數(shù)的執(zhí)行 解決方法使用自定義Hook 見(jiàn)下一標(biāo)題
3.模擬componentWillUnmount
useEffect(() => { return () => { console.log('Child 銷毀了') } }) // 返回一個(gè)函數(shù) 在銷毀時(shí)執(zhí)行
4.constructor
函數(shù)組件執(zhí)行的時(shí)候,就相當(dāng)于constructor
5.shouldComponentUpdate
后面的 React.memo和useMemo可以解決
6.render
函數(shù)組件的返回值就是render的返回值.
// 模擬render里面寫(xiě)邏輯 const X = (props) => { console.log('我是要寫(xiě)的邏輯') return ( <div>邏輯模擬</div> ) } const App = props => { let [childVisible, setChildVisible] = useState(true) const changeVisible = () => { setChildVisible(!childVisible) } return ( <div className='App'> {childVisible ? <button onClick={changeVisible}>{childVisible}</button> : <button onClick={changeVisible}>hide</button>} {/*{childVisible ? <Child/> : null}*/} <Child/> <X/> </div> ) } // 一個(gè)函數(shù)便是一個(gè)組件
3. 自定義 Hook 之 useUpdate
解決上面 n 值初次渲染就執(zhí)行的問(wèn)題
const App = props => { const [n, setN] = useState(0) const onClick = () => { setN(n + 1) } const [nUpdateCount, setNUpdateCount] = useState(0) useEffect(() => { // 初次渲染就執(zhí)行 + 1 setNUpdateCount(nUpdateCount + 1) }, [n]) useEffect(() => { // 初次渲染就執(zhí)行 判斷是否大于1 if(nUpdateCount > 1){ console.log('n變了') } },[nUpdateCount]) return ( <div className='App'> n值變成了:{n} <button onClick={onClick}>n+1</button> </div> ) } // 通過(guò)使用兩次 useEffect 第一個(gè)觸發(fā)第二個(gè) useEffect 函數(shù)計(jì)數(shù),大于0便是n值變化了
上面的代碼很亂 改進(jìn)一下
const useX = (fn, dep) => { // 這就是自定義 Hook 這就可以抽離成別的文件 const [count, setCount] = useState(0) useEffect(() => { setCount(x => x + 1) }, [dep]) useEffect(() => { if (count > 1) { fn() } }, [count,fn]) } const App = props => { const [n, setN] = useState(0) const onClick = () => { setN(n + 1) } useX(() => { console.log('n 變化了') }, n) return ( <div className='App'> n值變成了:{n} <button onClick={onClick}>n+1</button> </div> ) }
補(bǔ)充:函數(shù)組件代替 class 組件
為什么要用函數(shù)組件代替 class 組件?別問(wèn),簡(jiǎn)單!相比類組件來(lái)說(shuō),函數(shù)組件確實(shí)要簡(jiǎn)單太多, 不妨看一個(gè) +1 的例子:
class App extends React.Component { const App = props = > { constructor() { const[n, setN] = React.useState(0); super(); const addN = () = > { this.state = { setN(n + 1); n: 0 } }; return ( } < div > { n } addN = () = > { < button onClick = { addN } > +1 < /button></div > this.setState({ n: this.state.n + 1 });) }; } render() { return ( < div className = "App" > { this.state.n } < button onClick = { this.addN } > +1 < /button> </div > ); //這是公共的渲染部分 } const rootElement = document.getElementById("root"); } ReactDOM.render( < App / > , rootElement);
通過(guò)上面的例子你可以看出,同樣是實(shí)現(xiàn) +1 的操作,類組件要比函數(shù)組件復(fù)雜的多,類組件不僅涉及到 extends、setState 等 API,還會(huì)涉及到 this 的使用,而且代碼量還很多。反觀函數(shù)組件就要清爽的多,所以在開(kāi)發(fā)中推薦使用函數(shù)組件。
總結(jié)
到此這篇關(guān)于React中函數(shù)組件的文章就介紹到這了,更多相關(guān)React函數(shù)組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React團(tuán)隊(duì)測(cè)試并發(fā)特性詳解
這篇文章主要為大家介紹了React團(tuán)隊(duì)測(cè)試并發(fā)特性詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08React RenderProps模式運(yùn)用過(guò)程淺析
render props是指一種在 React 組件之間使用一個(gè)值為函數(shù)的 prop 共享代碼的技術(shù)。簡(jiǎn)單來(lái)說(shuō),給一個(gè)組件傳入一個(gè)prop,這個(gè)props是一個(gè)函數(shù),函數(shù)的作用是用來(lái)告訴這個(gè)組件需要渲染什么內(nèi)容,那么這個(gè)prop就成為render prop2023-03-03React中的useState和setState的執(zhí)行機(jī)制詳解
這篇文章主要介紹了React中的useState和setState的執(zhí)行機(jī)制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03react中實(shí)現(xiàn)修改input的defaultValue
這篇文章主要介紹了react中實(shí)現(xiàn)修改input的defaultValue方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05詳解Webpack+Babel+React開(kāi)發(fā)環(huán)境的搭建的方法步驟
本篇文章主要介紹了詳解Webpack+Babel+React開(kāi)發(fā)環(huán)境的搭建的方法步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01