react案例—实现最简登录

文中代码都是片段,主要说明主要逻辑,完整代码参考 github
用到的库是 react-router + react-redux

通过 react-route 的快速入门我们很容易可以得到这样的路由

最终效果

login.gif

主要逻辑

我们进一步来改造,实现进来默认到登录页,登录成功看到菜单及对应组件。
简单分析下需求:

  • 用户打开页面‘/’时,会先判断是否登录,我们用一个状态 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

image.png

这样 store 就注册好了,接下来改造文章开头的路由

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'})
  }
}
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐