react案例—實現最簡登錄
文中代碼都是片段,主要說明主要邏輯,完整代碼參考 github
用到的庫是 react-router + react-redux
通過 react-route 的快速入門我們很容易可以得到這樣的路由
最終效果
主要邏輯
我們進一步來改造,實現進來默認到登錄頁,登錄成功看到菜單及對應組件。
簡單分析下需求:
- 用戶打開頁面‘/’時,會先判斷是否登錄,我們用一個狀態 isLogin 來判斷
- 登錄成功之後,isLogin 會改變爲 true,並且 isLogin 和用戶信息會在路由組件中傳遞。
這裏使用 react-redux 來實現這樣一個狀態傳遞。
react-redux 提供了 connect 函數來將 state 映射到props上並傳遞給組件,使用之前需用 Provide 組件將原本的App包起來,將 store 作爲 props 傳遞。
src/store/index.js
創建store
import {createStore, combineReducers} from 'redux';
import {userReducer} from "./userReducer";
const store = createStore(combineReducers({user: userReducer}))
export default store;
src/store/userReducer.js
這裏的操作很簡單,只需要用戶登錄成功後,通過store.dispatch 將 isLogin 狀態更改爲 true
// 定義修改規則 登錄
const initalUserInfo = {
isLogin: false, //判斷是否登錄
};
export function userReducer(
state = {...initalUserInfo}, action) {
switch (action.type) {
case "LOGIN_SUCCESS":
return {
isLogin: true
};
default:
return state;
}
}
src/index.js
src/App.js
// 我們把之前的路由菜單改一下,非登錄狀態進入 /login,登錄狀態顯示菜單
function App(){
return (
<BrowserRouter>
<Route path='/login' component={LoginPage} />
<PrivateRoute path='/'>
<ul>
<li><Link to='/'>主頁</Link></li>
<li><Link to='/message'>消息</Link></li>
<li><Link to='/search'>發現</Link></li>
<li><Link to='/my'>我的</Link></li>
</ul>
<Switch>
<Route exact path='/' component={HomePage} />
<Route path='/message' component={MessagePage}/>
<Route path='/search' component={SearchPage}/>
<Route path='/my' component={MyPage}/>
</Switch>
</PrivateRoute>
</BrowserRouter>
)
}
src/route/privateRoute.js
privateRoute 在這裏起到路由守衛的作用,即進入頁面之前先判斷登錄狀態
import React from 'react';
import {Redirect, Route} from 'react-router-dom';
import {connect} from 'react-redux'
export default connect(
({user}) => ({
isLogin: user.isLogin
})
)(
function PrivateRoute({children, isLogin, ...rest}) {
return (
<Route
{...rest}
render={({location}) =>
isLogin ? (
children
) : (<Redirect
to={{
pathname: "/login", state:
{redirect: location.pathname}
}}
/>
)
}
/>
);
});
src/pages/loginPage.js
登錄頁面的邏輯主要在登錄成功之後的處理
// 表單提交
submit = ()=>{
const {username, password} = this.state;
// 這裏保留一個成功的用戶名和密碼
if (username === 'admin' && password === 'admin'){
store.dispatch({type: 'LOGIN_SUCCESS'})
this.props.history.push('/')
} else {
store.dispatch({type: 'LOGIN_FAILURE'})
}
}