摘要:將所有的需要鑒權(quán)的頁面放在例如下,只有在有微信相關(guān)鑒權(quán)的信息存在,才允許訪問接下來的界面,否則,容器內(nèi)甚至可以直接不渲染接下來的界面。而接下來的則是把路由導(dǎo)向至了一個微信端專用的。
搭建項目框架 新建項目
執(zhí)行如下代碼,用create-react-app來建立項目的基礎(chǔ)框架,然后安裝需要用到的依賴。
$ npx create-react-app my-test-project $ cd my-test-project $ yarn add react-router-dom react-redux prop-types redux redux-saga $ yarn start
完成后,應(yīng)用啟動在localhost的3000端口。
接入react-router-domreact-router-dom其實就是react-router 4.0,與之前的3.0有什么區(qū)別呢?react-router被一分為三。react-router、react-router-dom和react-router-native。
react-router實現(xiàn)了路由的核心的路由組件和函數(shù)。而react-router-dom和react-router-native則是基于react-router,提供了特定的環(huán)境的組件。
react-router-dom依賴react-router,安裝的時候,不用再顯示的安裝react-router, 如果你有機會去看react-router-dom的源碼,就會發(fā)現(xiàn)里面有些組件都是從react-router中引入的。
新建layout在/src下新建layout目錄。為什么要新建layout目錄,因為有可能我們會用到多個layout,layout是一個什么樣的概念?
例如這個應(yīng)用需要提供一部分功能在微信使用。那么進入所有微信的相關(guān)界面下都要進行鑒權(quán)。沒有鑒權(quán)信息就不允許訪問,但是這個服務(wù)仍然有所有人都可以訪問的路由。使用layout可以很好的幫我們解決這個問題。
將所有的需要鑒權(quán)的頁面放在例如WechatContainer下,只有在有微信相關(guān)鑒權(quán)的信息存在,才允許訪問接下來的界面,否則,容器內(nèi)甚至可以直接不渲染接下來的界面。
在/src/layout下新建兩個文件,分別是AppLayout.js、WechatLayout.js。
AppLayout.js的代碼如下。在這個layout中,首頁就是單純的一個路由,導(dǎo)向至首頁。而接下來的/wechat則是把路由導(dǎo)向至了一個微信端專用的layout。
import React, { Component } from "react"; import Home from "../routes/home"; import WechatLayout from "./WechatLayout"; import { Route, Switch } from "react-router-dom"; /** * 項目入口布局 * 在此處根據(jù)一級路由的不同進入不同的container * 每個container有自己不同的作用 * * 在react-router V4中,將原先統(tǒng)一在一處的路由分散到各個模塊中,分散到各個模塊當(dāng)中 * 例如: WechatLayout的路由為/wechat 表示到該layout下的默認(rèn)路徑 */ class AppLayout extends Component { constructor(props) { super(props); this.state = {}; } render() { return (); } } export default AppLayout;
WechatLayout.js的代碼如下。在這個layout中,我們就可以對訪問該路由的用戶進行鑒權(quán)。如果沒有權(quán)限,我們可以直接限制用戶的訪問,甚至直接不渲染render中的數(shù)據(jù)。
例如,我們可以在componentWillMount中或者在render中,根據(jù)當(dāng)前的state數(shù)據(jù),對當(dāng)前用戶進行鑒權(quán)。如果沒有權(quán)限,我們就可以將當(dāng)前頁面重定向到?jīng)]有權(quán)限的提示界面。
import React, { Component } from "react"; import Home from "../routes/wechat/home"; import { Route, Switch } from "react-router-dom"; import { connect } from "react-redux"; class WechatLayout extends Component { constructor(props) { super(props); this.state = {}; } componentWillMount() { } render() { const className = "Wechat-Layout"; return (新建routes); } } const mapStateToProps = state => ({ reducer: state.wechatLayout }); export default connect(mapStateToProps)(WechatLayout);Our Manage Layout
新建/src/routes/home/index.js,代碼如下。
import React, { Component } from "react"; import {Link} from "react-router-dom"; class Home extends Component { constructor(props) { super(props); this.state = {}; } render() { const className = "Home"; return (); } } export default Home;This is Home
Manage Home
新建/src/routes/wechat/home/index.js, 代碼如下。在代碼中可以看到,觸發(fā)reducer很簡單,只需要調(diào)用dispatch方法即可。dispatch中的payload就是該請求所帶的參數(shù),該參數(shù)會傳到saga中間層,去調(diào)用真正的后端請求。并在請求返回成功之后,調(diào)用put方法更新state。
import React, { Component } from "react"; import {connect} from "react-redux"; class Home extends Component { constructor(props) { super(props); this.state = {}; } componentWillMount() { this.props.dispatch({ type: "WATCH_GET_PROJECT", payload: { projectName: "tap4fun" } }); } render() { const className = "Wechat-Home"; return (新建container); } } const mapStateToProps = state => ({ reducer: state.wechat }); export default connect(mapStateToProps)(Home)Home
The project name is : { this.props.reducer.projectName }
在/src下新建container,在container中新建文件AppContainer.js。我們整個react應(yīng)用都裝在這個容器里面。AppContainer.js的代碼如下。
而其中的Provider組件,將包裹我們應(yīng)用的容器AppLayout包在其中,使得下面的所有子組件都可以拿到state。Provider接受store參數(shù)作為props,然后通過context往下傳遞。
import React, { Component } from "react"; import PropTypes from "prop-types"; import { Provider } from "react-redux"; import { BrowserRouter as Router } from "react-router-dom"; import AppLayout from "../layout/AppLayout"; class AppContainer extends Component { constructor(props) { super(props); this.state = {}; } static propTypes = { store: PropTypes.object.isRequired }; render() { const { store } = this.props; return (修改項目入口文件); } } export default AppContainer;
更新/src/index.js,代碼如下。在此處會將create出來的store容器當(dāng)作屬性傳入到Appcontainer中,作為我們應(yīng)用的狀態(tài)容器。
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import * as serviceWorker from "./serviceWorker"; import AppContainer from "./container/AppContainer"; import createStore from "./store/createStore"; const store = createStore(); ReactDOM.render(新建store, document.getElementById("root")); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: http://bit.ly/CRA-PWA serviceWorker.unregister();
新建/src/store/craeteStore.js,代碼如下。通過以下的方式,我們可以給redux添加很多中間件,甚至是自己寫的中間件。
比如,我們可以自己實現(xiàn)一個日志中間件,然后添加到中間件數(shù)組middleWares中,在創(chuàng)建redux的store的時候,應(yīng)用我們自己寫的中間件。
import { applyMiddleware, compose, createStore } from "redux"; import createSagaMiddleware from "redux-saga"; import rootReducer from "../reducers"; import rootSaga from "../saga"; export default function configureStore(preloadedState) { // 創(chuàng)建saga中間件 const sagaMiddleware = createSagaMiddleware(); const middleWares = [sagaMiddleware]; const middlewareEnhancer = applyMiddleware(...middleWares); const enhancers = [middlewareEnhancer]; const composedEnhancers = compose(...enhancers); // 創(chuàng)建存儲容器 const store = createStore(rootReducer, preloadedState, composedEnhancers); sagaMiddleware.run(rootSaga); return store; }
在這引入了redux-saga。我之前在使用redux的時候,幾乎在每個模塊都要寫相應(yīng)的action和reducer,然后在相應(yīng)的模塊文件中引入action的函數(shù),然后在使用mapDispatchToProps將該函數(shù)注入到props中,在相應(yīng)的函數(shù)中調(diào)用。并且,一個action不能復(fù)用,即使觸發(fā)的是相同的reducer。這樣就會出現(xiàn)很多重復(fù)性的代碼,新增一個模塊的工作也相對繁瑣了很多。
但是使用了redux-saga之后,只需要在reducer中定義好相應(yīng)類型的操作和saga就可以了。不需要定義action的函數(shù),不需要在文件中引入action中函數(shù),甚至連mapDispatchToProps都不需要,直接使用this.props.dispatch({ "type": "WATCH_GET_PROJECT" })就可以調(diào)用。而且,action可以復(fù)用。
新建saga新建/src/saga/index.js,代碼如下。
import { put, takeEvery } from "redux-saga/effects"; import { delay } from "redux-saga"; export function* fetchProject() { yield delay(1000); yield put({ type: "GET_PROJECT" }) } export default function * rootSaga() { yield takeEvery("WATCH_GET_PROJECT", fetchProject); }新建reducer
新建/src/reducers/wechat.js,代碼如下。
const initialState = { projectName: null }; export default function counter(state = initialState, action) { let newState = state; switch (action.type) { case "GET_PROJECT": newState.projectName = action.payload.projectName; break; default: break; } return {...newState} }
新建/src/reducers/index.js,代碼如下。
import { combineReducers } from "redux"; import Wechat from "./wechat"; export default combineReducers({ wechat: Wechat });
在這里我們使用了combineReducers。在之前的基于redux的應(yīng)用程序中,常見的state結(jié)構(gòu)就是一個簡單的JavaScript對象。
重新啟動應(yīng)用到此處,重新啟動應(yīng)用,就可以在http://localhost:3000/wechat/home下看到從reducer中取出的數(shù)據(jù)。
在頁面中,我們就可以通過代碼this.props.dispatch的方式,來觸發(fā)action。
參考https://github.com/mrdulin/bl...
https://cn.redux.js.org/docs/...
項目源代碼Github倉庫
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/100102.html
摘要:項目技術(shù)棧項目地址項目演示現(xiàn)在比較流行的腳手架應(yīng)該是,由官方開發(fā)。網(wǎng)上關(guān)于項目的目錄結(jié)構(gòu)也很多,那應(yīng)該怎么合理地去組織我們的目錄結(jié)構(gòu)呢為了處理這個問題,我參考了一些項目,然后把它們的優(yōu)點結(jié)合起來,最后寫了這個腳手架。 項目技術(shù)棧:react16+react-router4+antd-mobile2+mobx+axios+webpack4項目github地址:https://github...
摘要:下面會從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個子頁面對應(yīng)一個文件??偨Y(jié)上面就是最早版本的源碼,很簡潔的使用了等其目的也很簡單簡化相關(guān)生態(tài)的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯的,大大提升了開發(fā)效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態(tài)管理,以及Redux-saga中...
摘要:下面會從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個子頁面對應(yīng)一個文件??偨Y(jié)上面就是最早版本的源碼,很簡潔的使用了等其目的也很簡單簡化相關(guān)生態(tài)的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯的,大大提升了開發(fā)效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態(tài)管理,以及Redux-saga中...
摘要:下面會從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個子頁面對應(yīng)一個文件??偨Y(jié)上面就是最早版本的源碼,很簡潔的使用了等其目的也很簡單簡化相關(guān)生態(tài)的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯的,大大提升了開發(fā)效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態(tài)管理,以及Redux-saga中...
摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅持每天花分鐘來學(xué)習(xí)與思考。 今天的React題沒有太多的故事…… 半個月前出了248個Vue的知識點,受到很多朋友的關(guān)注,都強烈要求再出多些React相前的面試題,受到大家的邀請,我又找了20多個React的使用者,他們給出了328道React的面試題,由我整理好發(fā)給大家,同時發(fā)布在了前端面試每日3+1的React專題,希望對大家有所幫助,同時大...
閱讀 3996·2021-11-24 09:39
閱讀 1898·2021-11-02 14:41
閱讀 939·2019-08-30 15:53
閱讀 3556·2019-08-29 12:43
閱讀 1294·2019-08-29 12:31
閱讀 3164·2019-08-26 13:50
閱讀 887·2019-08-26 13:45
閱讀 1088·2019-08-26 10:56