Hello!大家好!昨天初步認識了Redux
後(真的非常初步XD),知道他如何管理資料了,那今天要來說說在Redux
手上的資料該怎麼傳給React
的組件!就請各位繼續看下去吧!
上一篇有提到Redux
和React
是兩個沒有相關的套件,所以他們之間需要一座橋樑,而那座橋樑就叫做react-redux
,我們得透過他讓React
的組件能夠讀到Redux
的資料,所以先來下載吧!
這裡提醒一下,如果大家是用昨天的專案繼續的話,別忘記要下載react
和react-dom
,然後還要再幫babel
多下載一個@babel/preset-react
,最後最後把該loader
放到webpack.config.js
當中,而如果是使用之前在練習react
的專案開發的話,就只需要另外裝redux
和react-redux
。
當看到這裡有點搞混不知道該怎麼做的話,也可以到我的gitHub這裡clone專案下來,下載後在該目錄下執行npm install
讓npm
根據package.json
的內容下載套件,也可以自行依照裡面的設定自行下載,順便熟悉一下專案開發的流程XD,而連結內有問題的話都可以在留言告訴我!
store
吧!搞定事前準備後就可以開始動手了!先從新同學Redux
開始,趁還沒忘掉在練習一次吧!
import {createStore} from "redux" //importRedux套件
//取得資料
const data = {message:[{key:"1",name:'神Q',message:'嗨!大家好啊!'},
{key:"2",name:'小馬',message:'早安啊!昨天有沒有好好發文?'},
{key:"3",name:'王子',message:'ㄛ!別說了,那真的超級累!'},
{key:"4",name:'神Q',message:'哈哈哈!加油啦!再一下就結束了!'},
{key:"5",name:'王子',message:'結束後我一定要爆睡一頓!'},]}
//設定動作,雖然現在是空的
const addMessage = article => ({type:'addMessage',payload:article})
//將描述各個動作對資料的行為
const rootReducer = (state = data, action) => {
switch (action.type) {
case "addMessage":
break;
default:
return state
}
}
//建立保管資料的store
const store = createStore(rootReducer)
//測試用加上去的,等等再把它拿掉:
window.store = store;
window.addMessage = addMessage;
昨天在講感覺還很複雜,但是今天做起來就覺得也滿單純XD,他主要分成幾個部分下去處理:
redux
套件的createStore
方法。createStore
建立一個store
。上方我把資料指定成前天簡單完成的留言板資料,我們先來確定一下資料是否正常被store
保管了:
可以看到他非常完美的保管著我們的資料,那現在就可以把測試的那兩行拿掉了!
接下來我們在資料夾內新增一個message.jsx
(貼心小提醒:記得要把這個檔案加入webpack.config.js
的打包對象中),並寫個class
組件先簡單把訊息條列出來:
import React from "react"
import ReactDOM from "react-dom"
class MessageList extends React.Component {
render(){
let message = this.props.data.map((item)=>{
return <li key={item.key}>{item.name}:{item.message}</li>
})
return(
<ul>
{message}
</ul>
)
}
}
class MessageForm extends React.Component {
render(){
return <MessageList />
}
}
ReactDOM.render(<MessageForm/>,document.getElementById('root'))
到這裡是不是還覺得輕輕鬆鬆!但是重頭戲來了,該怎麼把他們處理在一起呢?
react-redux
登場!首先我們先解釋一下react-redux
這個套件,本文一開始有說,他是負責兩個套件之間的資料傳遞,那在這裡複習一下「React
的最小單位是組件,而所有的資料為了一致性,會藉由props
將資料從父組件流向子組件。」
現在我們將資料用redux
統一管理,再將資料傳遞到組件中,這樣子的做法是不是很像父組件和子組件的關係?所以redux
就是父組件,什麼父組件?
Provider
!對的!雖然很突然,但是不要懷疑,react-redux
套件提供了Provider
組件的store
屬性來傳遞上面用建立的store
的資料,但是仔細想想,store
把它寫在index.js
中,message
組件寫在message.jsx
中,該怎麼把store
從idnex.js
傳到message.jsx
呢?
我們可以用export default
!把store
丟出來,讓其他檔案可以透過import...from...
的方式接收他,就像在使用其它套件一樣,如果好奇export default
是怎麼運作的可以參考這篇文章,他講得非常清楚,所以得先在index.js
的最下面增加一行export default store
。
export default store
再來就輪到message.jsx
了!首先要做的是匯入需要的物件,除了剛剛的store
外,還有更早之前講過的Provider
組件:
//從react-redux匯入Provider組件
import {Provider} from "react-redux"
//從index.js中匯出store,如果大大的路徑和我不同,記得要改一下!
import store from "./index.js"
接下來要宣告一個mapStateToProps
函式,我們將用它來指定需要哪些資料,例如上方的store
資料長這樣:
const data = {message:[{key:"1",name:'神Q',message:'嗨!大家好啊!'},
{key:"2",name:'小馬',message:'早安啊!昨天有沒有好好發文?'},
{key:"3",name:'王子',message:'ㄛ!別說了,那真的超級累!'},
{key:"4",name:'神Q',message:'哈哈哈!加油啦!再一下就結束了!'},
{key:"5",name:'王子',message:'結束後我一定要爆睡一頓!'},]}
很明顯要取的資料就是存在message
中那個陣列,所以mapStateToProps
這麼寫:
//上方的data會被傳入這個function中的state
const mapStateToProps = state => {
/*透過回傳的物件來指定要取的資料,
這裡把message取走,然後key值用data回傳*/
return { data: state.message }
}
好的!message
組件有了,用來取資料的mapStateToProps
也建好了,接下來要做連線了吧!用剛剛提到的Provider
組件!等等嘛!先不要急,在這之前得用connect
方法來將message
組件和mapStateToProps
連線,且他會回傳一個新的組件,不過我們剛剛還沒有import
這個方法對吧!所以要記得先匯入後再使用:
//從react-redux匯入connect
import {connect} from "react-redux"
.
.
.
/*建立一個變數來存放connect回傳的組件,
注意這邊不是兩個參數哦!是兩個括號,
第一個給入mapStateToProps,第二個給要使用資料的組件*/
const List = connect(mapStateToProps)(MessageList)
到這裡不知道大家會不會好奇,為什麼要為取資料的function
取名做mapStateToProps
?直接叫做getdata
不是簡單方便嗎?因為在redux
的官方文檔中connect
的函式接收的參數是這樣子:
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
所以為了讓其他開發者,或是可能會看到程式碼的其他人一看就知道,這個函式就是要傳到connect
中用來指定要從store
中取得資料的!雖然使用getData
也可以,不過其他人為了知道這是在做什麼的,就還要再追程式碼到connent
才會知道,所以跟著大眾命名也是很重要的事情!
做了那麼多前置作業,總該輪到Provider
了吧!不然我翻臉哦!沒錯!是該輪到他了!
使用前要注意哦!因為上面用connect
所回傳的是一個組件,他會取代我們傳入的組件,也就是說上方的MessageList
在這時候已經變成List
了!所以我們不只要在MessageForm
組件中增加Provider
組件,還要把原本的MessageList
改為List
:
class MessageForm extends React.Component {
render(){
return(
//使用Provider組件記得要透過store屬性傳入import進來的store資料
<Provider store={store}>
//原本的MessageList已經被connect包成List了
<List />
</Provider>
)
}
}
天哪!做了那麼多事情,該不會還有吧?哈哈哈!已經沒了XD,我們一起打包後,開網頁看看成果吧!
明明是簡單的畫面,但卻不知如何覺得很感動對吧XD,終於終於看見redux
的成果了!而且React
的家族感覺越來越強大!以下附上GitHub的連結,這一次動的檔案不只一個,所以直接給目錄,可以透過目錄點擊檔案看程式碼:
GitHub程式碼
GitPage頁面
今天先簡單熟悉Redux
傳遞資料到React
組件內props
的過程,但是Redux
能做的可不只是這樣子!大家應該還記得昨天有在redux
做到異動資料這件事情吧!不過不要緊張,今天已經結束了XD,,明天會上面的進度開始做!把留言功能給做出來!
最後感謝各位大大的觀看!如果有任何文章內有任何問題,再麻煩留言告訴我!小弟會盡快修正會補充文章內容的!謝謝各位
參考資料: