當前位置:
首頁 > 知識 > React 實踐項目(二)

React 實踐項目(二)

上回說到用React寫了一個帶Header的首頁,我們這次實踐就使用Redux進行狀態管理Rudex

應用中所有的 state 都以一個對象樹的形式儲存在一個單一的 store 中。

惟一改變 state 的辦法是觸發 action,一個描述發生什麼的對象。

為了描述 action 如何改變 state 樹,你需要編寫 reducers。

我們接下來開始開始進行登陸與註冊的狀態管理

首先在 src目錄下創建redux文件夾,目錄如下

digag
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ └── favicon.ico
│ └── index.html
│ └── manifest.json
└── src
└── components
└── Index
└── Header.js
└── LoginDialog.js
└── RegisterDialog.js
└── containers
└── App
└── App.js
└── App.css
└── redux
└── action
└── users.js
└── reducer
└── auth.js
└── users.js
└── sagas
└── api.js
└── sagas.js
└── selectors.js.js
└── users.js
└── store
└── store.js
└── App.test.js
└── index.css
└── index.js
└── logo.svg
└── registerServiceWorker.js

記得在 package.json中更新依賴

接下來我會開始解釋關鍵代碼
  • action
    action/users.js

/*
* action 類型
*/
export const REGISTER_USER = "REGISTER_USER";
// 省略其他action 類型

/*
* action 創建函數
*/
export const registerAction = (newUser) => {
return{
type:REGISTER_USER,
data: newUser,
}
};
// 省略其他 action 創建函數

  • reducer
    reducer/users.js

//Immutable Data 就是一旦創建,就不能再被更改的數據。
//對 Immutable 對象的任何修改或添加刪除操作都會返回一個新的 Immutable 對象。
import Immutable from "immutable";
//從 action 導入需要的 action 類型
import {REGISTER_USER, REGISTER_USER_SUCCESS, REGISTER_USER_FAILURE} from "../action/users";

// 初始化狀態
const initialState = Immutable.fromJS({
newUser: null,
error: null,
saveSuccess: false,
});

// reducer 就是一個純函數,接收舊的 state 和 action,返回新的 state。
export const users = (state = initialState, action = {}) => {
switch (action.type) { // 判斷 action 類型
case REGISTER_USER:
return state.merge({ // 更新狀態
"newUser": action.data,
"saveSuccess": false,
"error": null,
});
case REGISTER_USER_SUCCESS:
return state.set("saveSuccess", action.data);
case REGISTER_USER_FAILURE:
return state.set("error", action.data);
default:
return state
}
};

  • store
    store/store.js

import {createStore, combineReducers, applyMiddleware } from "redux";
import createSagaMiddleware from "redux-saga"
import * as reducer from "../reducer/users";

import rootSaga from "../sagas/sagas";

const sagaMiddleware = createSagaMiddleware;

const store = createStore(
combineReducers(reducer),
applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(rootSaga);

export default store;

然後在入口文件使用 store

src/index.js

import {Provider} from "react-redux";
import store from "./redux/store/store";
// 省略其他

ReactDOM.render(


, document.getElementById("root")
);

在 App.js 中獲取 action 和 狀態

import {registerAction, loginAction} from "../../redux/action/users";
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
//省略其他

class App extends Component {

render{
return(

//省略

)
}

}

export default connect(
(state) => {
// 獲取狀態 state.users 是指 reducer/users.js 文件中導出的 users
// 可以 `console.log(state);` 查看狀態樹
return { users: state.users }
},
(dispatch) => {
return {
// 創建action
registerActions: bindActionCreators(registerAction, dispatch),
loginActions: bindActionCreators(loginAction, dispatch),
}
})(App);
// 在App 組件的props里就有 this.props.users this.props.registerActions this.props.loginActions 了
// 需要注意的是這裡this.props.users是Immutable 對象,取值需要用this.props.users.get("newUser")
// 也可在 reducer 里改用 js 普通對象

裝飾器版本:

需要在Babel中開啟裝飾器

裝飾器插件babel-plugin-transform-decorators-legacy

@connect(
(state) => {
console.log(state);
return ({
users: state.users,
});
},
{registerActions: registerAction, loginActions: loginAction}
)

最後把 registerActions傳給RegisterDialog子組件,

src/components/Index/RegisterDialog.js

// 省略其他代碼
handleSubmit = (e) => {
e.preventDefault;
// 驗證表單數據
this.refs.user.validate((valid) => {
if (valid) {
// this.state.user 為表單收集的 用戶註冊數據
this.props.registerActions(this.state.user);
this.setState({loading: true});
}
});
};

流程是:

  • 調用 action
    this.props.registerActions(this.state.user);
    返回action 為

{
type:REGISTER_USER,
data: this.state.user,
}

  • reducer 根據action類型更新狀態

switch (action.type) {
case REGISTER_USER:
return state.merge({
"newUser": action.data,
"saveSuccess": false,
"error": null,
});
//省略其他代碼

這時我們的store里的狀態 newUser就被更新為 註冊彈窗里收集的數據

到這裡都還是同步的action,而註冊是一個非同步的操作。

下篇文章會介紹如何使用 redux-saga 進行非同步操作。

redux-saga 已經在使用了,有興趣的可以自行查看代碼理解。

記得點star:)

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

「PHP」最詳細PHP從入門到精通(五)——PHP錯誤處理
vue2.0引入騰訊地圖
jsPlumb之流程圖項目總結及實例
geotrellis使用(二十九)遷移geotrellis至1.1.1版

TAG:達人科技 |

您可能感興趣

Accurate檢測項目和意義
Repulse Game Studio將推出第二個VR項目《伊拉貢》
Oculus啟動第三屆VR for Good計劃,繼續支持實驗性項目
Github 項目推薦 用PyTorch 實現 OpenNMT
Blazor正式成為Microsoft官方.NET 和WebAssembly項目
Oculus公布首批VR影視創作者實驗室Creators Lab入選項目
Exchange Union項目進展
SpaceX衛星互聯網項目Starlink大事記
項目評級——RewardMob
谷歌Research和Google.ai合併 統一成全新AI項目
為刺激VR/AR領域發展 Digital Catapult再次啟動Augmentor項目
使用Jira software+Structure實現大規模跨團隊項目管理
GitHub項目 | PyTorch 中文手冊
Ether Universe項目評測:第四代跨鏈技術實現「異鏈」Tokens直接交換
lncRNA實戰項目-第五步-差異表達的mRNA和lncRNA
一個lncRNA項目的實戰
Apache頂級項目孵化的故事-CarbonData成長史
如何在 Emacs 中使用 Magit 管理 Git 項目
eBay推出「Always Open on eBay」項目
從論文到測試:Facebook Detectron開源項目初探