摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。惟一改變的辦法是觸發(fā),一個(gè)描述發(fā)生什么的對象。對對象的任何修改或添加刪除操作都會(huì)返回一個(gè)新的對象。從導(dǎo)入需要的類型初始化狀態(tài)就是一個(gè)純函數(shù),接收舊的和,返回新的。
React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時(shí)間了,現(xiàn)在就開始用 React+Redux 進(jìn)行實(shí)戰(zhàn)!
React 實(shí)踐項(xiàng)目 (一)
本次實(shí)踐代碼
部署好的網(wǎng)址
上回說到用React寫了一個(gè)帶Header的首頁,我們這次實(shí)踐就使用Redux進(jìn)行狀態(tài)管理 Rudex應(yīng)用中所有的 state 都以一個(gè)對象樹的形式儲(chǔ)存在一個(gè)單一的 store 中。
惟一改變 state 的辦法是觸發(fā) action,一個(gè)描述發(fā)生什么的對象。
為了描述 action 如何改變 state 樹,你需要編寫 reducers。
我們接下來開始開始進(jìn)行登陸與注冊的狀態(tài)管理
首先在 src 目錄下創(chuàng)建 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 中更新依賴
接下來我會(huì)開始解釋關(guān)鍵代碼action
action/users.js
/* * action 類型 */ export const REGISTER_USER = "REGISTER_USER"; // 省略其他action 類型 /* * action 創(chuàng)建函數(shù) */ export const registerAction = (newUser) => { return{ type:REGISTER_USER, data: newUser, } }; // 省略其他 action 創(chuàng)建函數(shù)
reducer
reducer/users.js
//Immutable Data 就是一旦創(chuàng)建,就不能再被更改的數(shù)據(jù)。 //對 Immutable 對象的任何修改或添加刪除操作都會(huì)返回一個(gè)新的 Immutable 對象。 import Immutable from "immutable"; //從 action 導(dǎo)入需要的 action 類型 import {REGISTER_USER, REGISTER_USER_SUCCESS, REGISTER_USER_FAILURE} from "../action/users"; // 初始化狀態(tài) const initialState = Immutable.fromJS({ newUser: null, error: null, saveSuccess: false, }); // reducer 就是一個(gè)純函數(shù),接收舊的 state 和 action,返回新的 state。 export const users = (state = initialState, action = {}) => { switch (action.type) { // 判斷 action 類型 case REGISTER_USER: return state.merge({ // 更新狀態(tài) "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(在 App.js 中獲取 action 和 狀態(tài), document.getElementById("root") );
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) => { // 獲取狀態(tài) state.users 是指 reducer/users.js 文件中導(dǎo)出的 users // 可以 `console.log(state);` 查看狀態(tài)樹 return { users: state.users } }, (dispatch) => { return { // 創(chuàng)建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(); // 驗(yàn)證表單數(shù)據(jù) this.refs.user.validate((valid) => { if (valid) { // this.state.user 為表單收集的 用戶注冊數(shù)據(jù) this.props.registerActions(this.state.user); this.setState({loading: true}); } }); };流程是:
調(diào)用 action
`this.props.registerActions(this.state.user);` 返回action 為
{ type:REGISTER_USER, data: this.state.user, }
reducer 根據(jù)action類型更新狀態(tài)
switch (action.type) { case REGISTER_USER: return state.merge({ "newUser": action.data, "saveSuccess": false, "error": null, }); //省略其他代碼
這時(shí)我們的store里的狀態(tài) newUser 就被更新為 注冊彈窗里收集的數(shù)據(jù)
到這里都還是同步的action,而注冊是一個(gè)異步的操作。
下篇文章會(huì)介紹如何使用 redux-saga 進(jìn)行異步操作。
redux-saga 已經(jīng)在使用了,有興趣的可以自行查看代碼理解。
記得點(diǎn)star:)
項(xiàng)目代碼地址:https://github.com/DigAg/diga...
vue2版項(xiàng)目代碼地址:https://github.com/DigAg/diga...
相應(yīng)后端項(xiàng)目代碼地址:https://github.com/DigAg/diga...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83913.html
摘要:隨著應(yīng)用的復(fù)雜程度越來越高,很多公司越來越重視前端單元測試。最后我們可以利用覆蓋率來看下用例的覆蓋程度是否足夠一般來說不用刻意追求,根據(jù)實(shí)際情況來定單元測試是測試驅(qū)動(dòng)開發(fā)的基礎(chǔ)。 隨著 Web 應(yīng)用的復(fù)雜程度越來越高,很多公司越來越重視前端單元測試。我們看到的大多數(shù)教程都會(huì)講單元測試的重要性、一些有代表性的測試框架 api 怎么使用,但在實(shí)際項(xiàng)目中單元測試要怎么下手?測試用例應(yīng)該包含哪...
摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。并且這個(gè)任務(wù)是最后被啟動(dòng)的那個(gè)。如果之前已經(jīng)有一個(gè)任務(wù)在執(zhí)行,那之前的這個(gè)任務(wù)會(huì)自動(dòng)被取消。如果我們允許多個(gè)實(shí)例同時(shí)啟動(dòng)?;蛘咧钡奖涣?,如果是這種情況,將在中拋出一個(gè)錯(cuò)誤。完整項(xiàng)目代碼地址 React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時(shí)間了,現(xiàn)在就開始用 React+R...
摘要:基于全家桶寫作新聞一體綜合應(yīng)用的實(shí)踐總結(jié)在線地址大家伙兒們,又見面了。參照但不可否認(rèn)非常符合的思想,都在處理大規(guī)模數(shù)據(jù)時(shí)彰顯優(yōu)勢。最好的辦法是使用部署環(huán)境。細(xì)致的拆分,解耦性更好,以為單位進(jìn)行修改時(shí),大大降低誤傷率的同時(shí),隔離無關(guān)的信息。 ?CoderPad-基于React全家桶寫作/新聞一體綜合應(yīng)用的實(shí)踐總結(jié) showImg(https://segmentfault.com/img/...
摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅(jiān)持每天花分鐘來學(xué)習(xí)與思考。 今天的React題沒有太多的故事…… 半個(gè)月前出了248個(gè)Vue的知識(shí)點(diǎn),受到很多朋友的關(guān)注,都強(qiáng)烈要求再出多些React相前的面試題,受到大家的邀請,我又找了20多個(gè)React的使用者,他們給出了328道React的面試題,由我整理好發(fā)給大家,同時(shí)發(fā)布在了前端面試每日3+1的React專題,希望對大家有所幫助,同時(shí)大...
摘要:也就是說不應(yīng)該有公開的,所有都應(yīng)該是私有的,只能有公開的。允許使用方法設(shè)置監(jiān)聽函數(shù),一旦發(fā)生變化,就自動(dòng)執(zhí)行這個(gè)函數(shù)。用一個(gè)叫做的純函數(shù)來處理事件??梢酝ㄟ^得到當(dāng)前狀態(tài)。在中,同步的表現(xiàn)就是發(fā)出以后,立即算出。 這篇文章試著聊明白這一堆看起來挺復(fù)雜的東西。在聊之前,大家要始終記得一句話:一切前端概念,都是紙老虎。 不管是Vue,還是 React,都需要管理狀態(tài)(state),比如組件之...
閱讀 1734·2021-11-22 12:09
閱讀 1461·2019-08-30 13:22
閱讀 2094·2019-08-29 17:00
閱讀 2644·2019-08-29 16:28
閱讀 2956·2019-08-26 13:51
閱讀 1183·2019-08-26 13:25
閱讀 3245·2019-08-26 12:14
閱讀 3015·2019-08-26 12:14