whay write this: 不少小白在看過不少教程以後仍然在敲代碼的時候不清楚應該以什麼樣的步驟進行,那麼這篇文章就一步一步分解整個過程,慢動做回放讓你們看的清清楚楚明明白白。react
這個小Demo的功能是在input標籤中輸入內容,同步顯示在上方的p標籤內,DEMO很簡單,大神們輕噴~?git
項目代碼在這裏:https://github.com/oliyg/redu...github
clone: https://github.com/oliyg/redu...redux
廢話很少說app
首先上圖:ide
/* _________ ____________ ___________ | | | | | | | Action |------------▶| Dispatcher |------------▶| callbacks | |_________| |____________| |___________| ▲ | | | | | _________ ____|_____ ____▼____ | |◀----| Action | | | | Web API | | Creators | | Store | |_________|----▶|__________| |_________| ▲ | | | ____|________ ____________ ____▼____ | User | | React | | Change | | interactions |◀--------| Views |◀-------------| events | |______________| |___________| |_________| */ 圖片來源:[redux-tutorial](https://github.com/happypoulp/redux-tutorial/blob/master/00_introduction.js)
上圖是你們再熟悉不過的redux數據流,從這個圖中咱們能夠按照下面這個流程來敲代碼:函數
component(渲染UI) -> action(定義用戶操做動做) -> reducer(處理action動做) -> store(處理reducer綁定state和dispatch) -> component(用connect綁定component、用Provider從新渲染UI) -> ...
這裏使用了create-react-app安裝並start後把一些沒用的文件清理掉,增長咱們本身的文件ui
文件目錄以下:this
src component/ Texture.js action/ action.js reducer/ reducer.js store/ store.js App.js
好,目錄文件大概就是這樣子,正式開始敲代碼spa
個人位置:component/Texture.js
首先從component開刀(View視圖):
引入必要的依賴:
import React from 'react';
建立component(這裏省去了propsTypes和defaultProps,僅僅爲了方便展現):
const Texture = (props) => ( <div> <h2>{props.str}</h2> <input onChange={props.onChange} placeholder={props.placeholder} /> </div> );
個人位置action/action.js
而後定義action,在這個例子中,咱們只有一個動做,修改input值:onChange,在action中命名爲onChangeAction,並傳入一個參數e,返回包含type和value值的對象,最後暴露模塊:
const onChangeAction = (e) => ( { type: 'INPUTCHANGE', value: e.target.value } ); export default onChangeAction;
個人位置reducer/reducer.js
定義完action以後,咱們天然是想辦法處理這個action,那麼下一步就是建立reducer:
reducer接收兩個參數,並返回新的state,第一個參數state要先設置初始值,不然返回undefined,第二個參數action,接收可能接收到的action參數。
state中設置咱們在component中要用到並綁定在視圖中顯示的props值,就是此前定義的str和placeholder
在reducer內部,須要用到switch檢測action的type並根據不一樣的type來處理相應的action
須要注意的是,咱們必需要記得在default狀況下返回state,不然若無匹配的action.type,state就會丟失。
const reducer = (state = { str: '✒️write something: ', placeholder: 'here?' }, action) => { switch (action.type) { case 'INPUTCHANGE': return { str: action.value }; default: return state; } }; export default reducer;
個人位置:store/store.js
咱們知道reducer存在於store內,既然action和reducer都配置好了,接下來就輪到store了
引入redux中createStore模塊和以前定義好的reducer,建立store:
import { createStore } from 'redux'; import reducer from '../reducer/reducer'; const store = createStore(reducer); export default store;
個人位置:component/Texture.js
處理完成後咱們再回到component中:
這麼一來,咱們只須要將store中的state和dispatch分別綁定在component中便可打通store中的state和component中的props的聯繫了,那麼咱們只須要react-redux提供的connect和Provider便可:
導入相關模塊:
import { Provider, connect } from 'react-redux'; import store from '../store/store'; import onChangeAction from '../action/action';
建立mapStateToProps和mapDispatchToProps兩個函數:
const mapStateToProps = (state) => { return ({ str: state.str, placeholder: state.placeholder }); }; const mapDispatchToProps = (dispatch) => { return ({ onChange: (e) => { return dispatch(onChangeAction(e)) } }); };
並將這倆貨和store經過connect和Provider綁定到視圖中:
const TextureConnect = connect(mapStateToProps, mapDispatchToProps)(Texture); const TextureWrapper = () => ( <Provider store={store}> <TextureConnect /> </Provider> ); export default TextureWrapper;
個人位置:App.js
最後,大功告成,在App.js中引入這個組件便可。
//requirement import React from 'react'; import TextureWrapper from './component/Texture'; const App = () => ( <TextureWrapper /> ); export default App;
另外,component/Texture.js中視圖部分最好單獨出來,放在新建一個文件夾view目錄下,並被名爲TextureContainer.js引用,把其餘邏輯部分放後者。