react项目中的参数解构_一天入门React学习心得
一天入門React學習心得
閱讀前必讀
本文寫的倉促,算是一個學習筆記吧,算是一個入門級的學習文章。如果你剛剛入門,那么可能一些入門的視頻可能更加適合你。但如果具備一些知識,比如Vue,那么視頻就不適合了。建議看完本篇文章在腦海中過一遍映像,在去官網深讀,和一些深入文章,想來會有非常好的提升。
“一個框架不是看幾篇文章,寫寫Demo就能說自己會,熟悉。需要不斷實踐,踩坑,學習原理。多想才能掌握。我只是結合Vue進行的React學習,只是冰山一角罷了。充其量只是API的搬運工。
- - QAQ初始化項目
新手還是推薦官方的腳手架,通過npx來進行項目的初始化一個demo項目。
npx?create-react-app?項目名稱默認生成的目錄情況下,項目的解構就是這樣的。
Mode????????????????LastWriteTime?????????Length?Name----????????????????-------------?????????------?----
d-----??????????20.6.15?????14:21????????????????public
d-----??????????20.6.15?????16:41????????????????src
-a----??????????20.6.15?????14:21????????????310?.gitignore
-a----??????????20.6.15?????14:22????????????746?package.json
-a----??????????20.6.15?????14:21???????????2884?README.md
-a----??????????20.6.15?????14:22?????????526017?yarn.lock
隨后通過npm 或者 yarn 來將項目跑起來。執行shell后會自動打開一個瀏覽器,當看到localhost:3000渲染后。那么就可以開啟React大門了
#??npm?shell?命令npm?run?start
#?yarn?shell?命令
yarn?start
React元素渲染-JSX
在Vue中template模板得到大量的使用,只要你會寫HTML那么應該難不倒你這個小機靈鬼。而React則是使用了在函數中直接返回DOM。看起來非常的神奇,也導致了一些小伙伴在入門的時候會有點摸不著頭腦,但是如果有一定基礎,在Vue中寫過了Render 函數的話,我想上手起來還是非常容易的。它看起來是下面這個樣子的。其本質上就是一個createElement的過程。所以,將這種模板的渲染方式稱之為JSX。
import?React?from?'react';import?'./App.css';
function?App()?{
??return?(
????<div?className="App"><h1>你好呀h1><p>今天又是充滿希望的一天...p>div>
??);
}
export?default?App;
通過React的JSX模板引擎,最終將其渲染到DOM上
變量綁定
在Vue的模板中,通過{{}}兩個花括號來聲明約束,表示這個聲明中的字段是一個js的值,而不是一個文本。在React則是使用了{}一個花括號來做約定。那么就可以在DOM中使用js了。下面是一個Class組件,將state的text值綁定在DOM的。
class?App?extends?React.Component?{??constructor?(props)?{
????super(props)
????this.state?=?{
??????text:?'我是wangly19'
????}
??}
??updateText?()?{
????this.setState({
??????text:?'我是帥氣的wangly19'
????})
??}
??render?()?{
????return?(
??????<div?className="App"><p>我是一個動態的數據:?{this.state.text}p><button?onClick={?this.updateText.bind(this)?}>更換button>div>
????)
??}
}
結果
條件渲染
在Vue中,如果需要動態的渲染一個節點,是通過v-if指令來實現的,在React中呢,可以使用運算符來渲染元素。通過Vue來做一個對比吧。
“通過&&(或)運算符來達到v-if的一樣效果。
- - QAQrender?()?{??return?(
????<div?className="App"><p>我是一個動態的數據:?{this.state.text}p>
??????{/*?{?<p?v-if="true">2p>?}?*/}
??????{true?&&?<p>2p>}div>
??)
}
“
通過三元運算符可以來達到v-if和v-else一樣的效果。
- - QAQrender?()?{??return?(
????<div?className="App"><p>我是一個動態的數據:?{this.state.text}p>
??????{/*?{?<p?v-if="true">2p>?}?*/}
??????{true???<p>truep>?:?<p>falsep>}div>
??)
}
列表渲染
通過map方法來遍歷一些基本數據結構的節點。
“通過數據結構自帶的map可以遍歷出value,index,key 在return中返回節點信息。
- - QAQ事件處理
在JavaScript中,通過onClick來綁定一個事件。
<button?onclick="activeBuff">激活按鈕button>而在jsx中,則是通過onClick屬性,且后面加一個jsx渲染模板的方式。
“需要注意的是,Class組件下的this是不存在的,需要用戶手動為方法綁定this,在調用的點擊事件方法。
- - QAQthis.activeBuff.bind(this)?}>激活按鈕</button>組件
眾所周知,Vue和React都是組件化解決方案,那么在React中是如何創建一個組件的呢?在React新版本中,推出了React Hooks方案。所以現在主流的還是Class組件和Function組件。
Class組件
Class組件的創建方式非常的簡單,只需要創建一個Class類并且讓它繼承React.Component,在Render方法中return出JSX的模板。
同時通過構造函數,處理Props。并且聲明state狀態初始化一個對象,將Props掛載到super上。
class?App?extends?React.Component?{??constructor?(props)?{
????super(props)
????this.state?=?{
????}
??}
??//?render函數
??render?()?{
????return?(
??????<div?className="App"><p>我是Class組件p>div>
????)
??}
}
Function組件
隨著React Hooks發布,開發的主流也漸漸的轉入了函數組件,不過Class組件在舊項目中還是會用的。所以都學習一下。對比Class組件,函數組件就非常的簡單了。在函數內部返回一個render模板就OK了。如下:
import?React?from?'react'function?FunctionDemo?()?{
??return?(
????<div>
??????我是函數組件div>
??)
}
export?default?FunctionDemo
Class組件State狀態
這里著重的開個單章,主要是Class組件中的State值更改,因為函數組件最好使用的是hooks,所以單拎出來主要解一下Class組件下State狀態。在React不建議直接修改State的值,而是使用setState的方式更新狀態。
this.setState({??default:?'修改后的文件'
})
同樣的,setState后當前的值并不會直接改變。它是一個異步函數,在異步函數中可以拿到最新的狀態。
如果需要進行計算值的累加,推薦使用的是通過函數的返回值形式。
“這里的原理類似Vue的組件data的函數return方式。如果使用對象方式的話,在多個setState使用的話會被后面的任務覆蓋,從而直接執行一次
- - QAQ//?nothis.setState({?index:?this.state.index?+?1?});
this.setState({?index:?this.state.index?+?1?});
//?yes
this.setState({?index:?this.state.index?+?1?});
????this.setState({?index:?this.state.index?+?1?});
this.setState((prevState,?props)?=>?{
??return?{quantity:?prevState.quantity?+?1};
});
組件通信
組件通信是開發中經常用到的功能,可謂是靈魂之一了。那么React的組件通信是如何完成的呢?
子組件獲取父組件的值 Props
通過Props可以使子組件非常快捷的拿到父組件的傳遞過去的內容。
- 1.在子組件上添加屬性名稱和數據
- 2.在Class中使用Props
??super(props)
??this.state?=?{
????defaultText:?'我是默認的文字'
??}
}
- 3.使用
通過this.props.父組件綁定的屬性名稱
{?this.props.name?}</p>
定義默認的Props屬性
在Vue中可以定義Props的默認值,哪怕用戶沒有傳遞,就會顯示默認Props中定義的內容。
ClassDemo.defaultProps?=?{??name:?'我是默認的名稱'
??//?...?參數列表
}
子組件傳遞父組件
通過Props傳遞一個函數,當子組件需要改變父組件的值時,通過this.props.[函數]執行回調。
//?父組件class?App?extends?React.Component?{
??constructor?(props)?{
????super(props)
????this.state?=?{
??????childMessage:?'2222222222222222'
????}
??}
??onPropChange?(newVal)?{
????this.setState({
??????childMessage:?newVal
????})
??}
??render?()?{
????return?(
??????<div?className="App"><p>{?this.state.childMessage?}p><ClassDemo?onPropChange={?this.onPropChange.bind(this)?}>ClassDemo>
????????{/*?<FunctionDemo>FunctionDemo>?*/}div>
????)
??}
}
import?React?from?'react';
class?ClassDemo?extends?React.Component?{
??constructor?(props)?{
????super(props)
????this.state?=?{
??????defaultText:?'我是默認的文字'
????}
??}
??changeText?()?{
????this.props.onPropChange('111111111111111')
??}
??render?()?{
????return?(
??????<div?className="App"><button?onClick={?this.changeText.bind(this)?}>更改文本button>div>
????)
??}
}
export?default?ClassDemo;
圖
生命周期
看了官方的生命周期介紹,挺簡潔的。分別是組件模板選然后,已經準備就緒的時候,可以做組件加載后的一些邏輯操作,鎮樓神圖。
鎮樓神圖掛載
constructor
構造函數初始化,最先被執行,初始化State等等。
getDerivedStateFromProps
這是一個靜態方法,需要在前面增加static的屬性
render
渲染函數,返回渲染的內容,當頁面產生更新也會觸發該方法。
componentDidMount
組件掛載之后,這個時候組件已經掛載完畢了
更新
getDerivedStateFromProps
組件即將被更新,這里參數分別對應前后被修改的內容,通過返回一個布爾值告知是否需要更新視圖。
render
當視圖更新,那么Render也會重新更新
getSnapshotBeforeUpdate
getSnapshotBeforeUpdate在render之后componentDidUpdate之前輸出,類似于中間件用來做一些捕獲操作。
componentDidUpdate
getSnapshotBeforeUpdate,有三個參數prevProps,prevState,snapshot,表示之前的props,之前的state,和snapshot。snapshot是getSnapshotBeforeUpdate返回的值
constructor?(props)?{??super(props)
??this.state?=?{}
??console.log('1.constructor構造函數')
}
componentDidMount?()?{
??console.log('componentDidMount')
??Store.subscribe(()?=>?{
????this.setState({})
??})
}
static?getDerivedStateFromProps?(nextProps,?prevState)?{
??console.log('getDerivedStateFromProps')
??console.log(nextProps,?prevState)
??return?true
}
getSnapshotBeforeUpdate?(prevProps,?prevState)?{
??console.log(prevProps,?prevState)
??return?'top:?200'
}
componentDidUpdate?(prevProps,?prevState,?snapshot)?{
??console.log(prevProps,?prevState,?snapshot)
}
componentWillUnmount?()?{
??console.log('componentWillUnmount')
}
changeText?()?{
??Store.dispatch({
????type:?'changeName',
????value:?'我是ClassDemo中修改的名字:wangly'
??})
}
render?()?{
??console.log('3.render函數')
??return?(
????<div?className="App"><p>{?Store.getState().redux_name?}p>
??????{?this.state.redux_name?}<button?onClick={?this.changeText.bind(this)?}>更改文本button>div>
??)
}
卸載
componentWillUnmount
組件卸載,我們可以清除一些定時器,取消網絡請求。
組件插槽
插槽對于Vue來說并不是很陌生,在React中插入的節點會以Props的方式傳遞。可以通過pro1ps.children找到并且渲染出來。
//?父親組件this.onPropChange.bind(this)}><h1>插入的元素?h1>ClassDemo>//?子組件<div?className="App">
??{this.props.children}<button?onClick={this.changeText.bind(this)}>更改文本button>div>
Router路由
路由對于SPA應用來講可謂是重中之重,沒有它的話,那么這個頁面也就不能成為應用,只能稱之為頁面。兩者可謂天差地別。
安裝react-router-dom --save
#?shellnpm?install?react-router-dom?--save
創建路由模式
在Vue中都知道路由的mode有兩種,一種是hash一種是history模式。分別如下,通過引入不同的包來創建不同的Router。
//?histoty
import?{?BrowserRouter?as?Router,?Link,?Route?}?from?'react-router-dom';
//?hash
import?{?Link,?Route,?HashRouter?as?Router?}?from?'react-router-dom';
創建一個簡單的路由
通過as出來的Router包裹路由快,通過Link作為跳轉的行為容器。這樣一個基本的路由容器就完成。
“需要通過使Route進行對組件的聲明配置,才能被Link找到哦。
- - QAQimport?React?from?'react';//?histoty
import?{?BrowserRouter?as?Router,?Link,?Route?}?from?'react-router-dom';
//?hash
//?import?{?Link,?Route,?HashRouter?as?Router?}?from?'react-router-dom';
function?Page1?()?{
??return?(
????<h1>我是Page1h1>
??)
}
function?Page2?()?{
??return?(
????<h1>我是Page2h1>
??)
}
function?Page3?()?{
??return?(
????<h1>我是Page3h1>
??)
}
class?App?extends?React.Component?{
??constructor?(props)?{
????super(props)
????this.state?=?{
????}
??}
??render?()?{
????return?(
??????<div?className="App"><Router><ul><li><Link?to="page1">Page1Link>li><li><Link?to="page2">Page2Link>li><li><Link?to="page3">Page3Link>li>ul><Route?exact?path="/page1"?component={?Page1?}>Route><Route?exact?path="/page2"?component={?Page2?}>Route><Route?exact?path="/page3"?component={?Page3?}>Route>Router>div>
????)
??}
}
export?default?App;
路由傳值
路由傳遞參數一般使用param和query參數。通過給to傳遞一個對象的方式來進行數據的傳遞。可以看到,向page1的路由上添加了一個:id表示需要傳遞param的id的值,同時聲明了search的文本和state對象多種方式傳遞了參數。以便根據不同的場景使用。
;<div?className="App"><Router><ul><li><Linkto={{pathname:?'/page1/10',search:?'?roles=[10,?20]',state:?{?name:?'wangly19'?},??????????}}
????????>
??????????Page1Link>li><li><Link?to="page2">Page2Link>li><li><Link?to="page3">Page3Link>li>ul><Route?exact?path="/page1/:id"?component={Page1}>Route><Route?exact?path="/page2"?component={Page2}>Route><Route?exact?path="/page3"?component={Page3}>Route>Router>div>
手動跳轉
當你使用History路由的時候,某些時候需要主動的跳轉道某個路由,這個時候又不能去觸發節點行為,所以這個時候就可以通過API的方式,進行跳轉。使用方式和Vue大差不差。
//?跳轉頁面this.props.history.push(參數和to的內容像素)
this.props.history.push('page1')
//?重定向頁面
this.props.history.replace('page2')
當然還有hash的go方法。
Redux狀態管理
Redux是類似于Vuex的一個全局狀態解決方案,它的功能主要是用來存儲公有全局狀態。來方便管理一些共有配置參數,解決業務體積大,結構復雜的項目提供好的狀態管理。
“如果項目不是特別需要,盡量不去使用它。
- - QAQ安裝Redux
#?shellnpm?install?redux?--save
創建Store State
看到官方的Demo,是非常容易懂的。下面是官方的代碼,一眼就能看出流程。
import?{?createStore?}?from?'redux'/**
?*?This?is?a?reducer,?a?pure?function?with?(state,?action)?=>?state?signature.
?*?It?describes?how?an?action?transforms?the?state?into?the?next?state.
?*
?*?The?shape?of?the?state?is?up?to?you:?it?can?be?a?primitive,?an?array,?an?object,
?*?or?even?an?Immutable.js?data?structure.?The?only?important?part?is?that?you?should
?*?not?mutate?the?state?object,?but?return?a?new?object?if?the?state?changes.
?*
?*?In?this?example,?we?use?a?`switch`?statement?and?strings,?but?you?can?use?a?helper?that
?*?follows?a?different?convention?(such?as?function?maps)?if?it?makes?sense?for?your
?*?project.
?*/
function?counter(state?=?0,?action)?{
??switch?(action.type)?{
????case?'INCREMENT':
??????return?state?+?1
????case?'DECREMENT':
??????return?state?-?1
????default:
??????return?state
??}
}
//?Create?a?Redux?store?holding?the?state?of?your?app.
//?Its?API?is?{?subscribe,?dispatch,?getState?}.
let?store?=?createStore(counter)
//?You?can?use?subscribe()?to?update?the?UI?in?response?to?state?changes.
//?Normally?you'd?use?a?view?binding?library?(e.g.?React?Redux)?rather?than?subscribe()?directly.
//?However?it?can?also?be?handy?to?persist?the?current?state?in?the?localStorage.
store.subscribe(()?=>?console.log(store.getState()))
//?The?only?way?to?mutate?the?internal?state?is?to?dispatch?an?action.
//?The?actions?can?be?serialized,?logged?or?stored?and?later?replayed.
store.dispatch({?type:?'INCREMENT'?})
//?1
store.dispatch({?type:?'INCREMENT'?})
//?2
store.dispatch({?type:?'DECREMENT'?})
//?1
- 創建Stoge
const?modeStore?=?{
??redux_name:?'我是Redux中聲明的名稱:wangly19'
}
//?聲明Reducer
const?reducer?=?(state?=?modeStore,?action)?=>?{
??return?state
}
//?createStore
import?{?createStore?}?from?'redux';
import?reducer?from?'./reducer'
const?store?=?createStore(reducer)
export?default?store
- 視圖渲染
{?Store.getState().redux_name?}
- 觸發更新行為dispatch
//?dispatch
changeText?()?{
??Store.dispatch({
????type:?'changeName',
??? value:?'我是ClassDemo中修改的名字:wangly'
??})
}
前提是,需要對action的方法做一個聲明。類似于Vuex的Action。
const?reducer?=?(state?=?modeStore,?action)?=>?{??switch?(action.type)?{
????case?'changeName':
??????const?newState?=?{...state}
??????console.log(state)
??????newState.redux_name?=?action.value
??????console.log(newState)
??????console.log(state)
??????return?newState
??
????default:
??????return?state;
??}
}
- 監聽變化。
作為行為觸發行為后更新視圖的憑證。在組件注銷時,注意銷毀它哦。
- - QAQcomponentDidMount?()?{??/**
???*?回調函數
???*/
??Store.subscribe(()?=>?{
????console.log(Store.getState().redux_name)
????this.setState({})
??})
}
Hooks
“Hooks我準備寫新的文章。
- - QAQ總結
學習React很多都是以Vue的思路先入個門,不至于一問三不知。也明白了知其一而知其三。如果有基礎那么學習起來其實并不是很困難。但是它的文檔并不如Vue的全面,且對于某些方面來說。花了一天時間整理一些基本的學習東西
“如果覺得對你有幫助,不妨點個贊哦。
- - QAQ參考資料
React文檔
react生命周期個人理解
react模板
React路由
Redux
總結
以上是生活随笔為你收集整理的react项目中的参数解构_一天入门React学习心得的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qpython获取手机gps_基于Pyt
- 下一篇: python怎么做软件界面_python