从零开始react项目06

login组件

在pages文件夹中新建一个login文件夹,然后是熟悉的index.js style.js store文件夹

import React, { PureComponent } from "react";
// import { actionCreator } from "./store";
import { connect } from "react-redux";
import { LoginWrapper} from "./style";

class Login extends PureComponent {
    render() {
        return (
            <LoginWrapper>
                Login
            </LoginWrapper>
        )
    }
}
const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => ({
})
export default connect(mapStateToProps, mapDispatchToProps)(Login);

App.js中引入

import Login from "./pages/login/index.js";
class App extends Component {
  render() {
    return (。。。。。。
        <BrowserRouter>
          <Header />。。。
          <Route path="/login" exact component={Login}></Route>
			。。。
        </BrowserRouter>
      </Provider>
    );
  }
}

export default App;

每增加一个reducer,就要记得来总store这里,补充一下

import { combineReducers } from "redux-immutable"
import { reducer as headReducer } from "../common/header/store"
import { reducer as homeReducer } from "../pages/home/store"
import { reducer as loginReducer } from "../pages/login/store"
//引入redux-immutable,使全局state变成immutable对象
const reducer= combineReducers({
    header: headReducer,
    home: homeReducer,
    login: loginReducer
})
export default reducer;

在这里插入图片描述

修改header组件,如果已登录,显示"退出",否则显示“登录”

这就需要header组件获取到login下的数据
跳转到src/common/header/index.js文件,修改

render() {
  const { ... , login } = this.props;
  return(
         {
           login ? <Navitem className="right">退出登录</Navitem>:<Navitem className="right">登录</Navitem>
         }
......
}
const mapStateToProps = (state) => {
    return {
		。。。。
        login:state.getIn(["login","login"])
    }
}

同时,还需要增加路由,以便用户点击登录时,能够跳转到登录页面

{
  login ? <Navitem className="right">退出登录</Navitem>:
  <Link to="/login"><Navitem className="right">登录</Navitem></Link>
}

Login组件的点击登录功能实现

src/pages/login/index.js

ref的作用,我很不熟悉

class Login extends PureComponent {
    render() {
        return (

<Input placeholder="账号" ref={(input)=>{this.account=input} }></Input>
		!!!上面这句ref会把输入的内容赋值给this.account!!!
		
<Input placeholder="密码" type="password" ref={ (input)=>{this.password=input}}></Input>
		!!!上面这句ref会把输入的内容赋值给this.password!!!
		
<Button onClick={()=>this.props.login(this.account,this.password)}>登录</Button>
		!!!!一定记住,如果想传递参数,一定要用箭头函数的形式
        )
    }
}
const mapDispatchToProps = (dispatch) => ({
    login(accountElement,passwordElement) {
        console.log(accountElement, passwordElement);
        会打印出那两个组件
        console.log(accountElement.value, passwordElement.value);
        两个组件的值
    }
})

打印出来的结果如下
打印的结果

用户名和密码校验

需要把拿到的用户名和密码发送给后端,看匹不匹配

const mapDispatchToProps = (dispatch) => ({
    login(accountElement, passwordElement) {
        dispatch(actionCreator.login(accountElement.value, passwordElement.value))
    }
})

src/pages/login/store/actionCreator.js

这种网络请求是我的盲点

import axios from "axios";
export const login = (account, password) => {
    return (dispatch) => {
        axios.get("/api/login.json?account=" + account + "&password=" + password).then((res) => {
            console.log(res);
        })
    }
}

public/api/login.json
这个数据就是说任何人都能登录

{
    "success":true,
    "data":true
}

登陆成功后两件事:显示“退出登录”+跳转至首页

  1. 显示“退出登录
    src/pages/login/store/actionCreator.js
export const login = (account, password) => {
    return (dispatch) => {
        axios.get("/api/login.json?account=" + account + "&password=" + password).then((res) => {
            const result = res.data.data;
            if (result) {
                //如果登陆成功,要派发action修改login的数据
                dispatch(changeLogin())        
            } else {
                alert("登录失败")
            }
        })
    }
}

src/pages/login/store/reducer.js

import { fromJS } from "immutable";// 导入immutable模块中fromJS方法
//使用fromJS将其变为immutable对象数据(只能使用set、get)
import * as actionType from "./actionType";

const defaultState = fromJS({
  login:false
})
export default (state = defaultState, action) => {
  switch (action.type) {
    case actionType.CHANGE_LOGIN:
      return state.set("login", action.value);
    default:
        return state;
    }
}
;

实现登录成功后修改状态

  1. 跳转至首页
    login/index.js中获取login数据,如果当前login数据为true,就跳转到首页,否则就渲染“用户名”和“密码”输入页面
    注意:因为都在props里面,函数与变量不能够重名
。。。
import { Redirect } from "react-router-dom";  !!!!!!!注意这里的新组件
 
class Login extends PureComponent {
    render() {
        const { loginStatus } = this.props;
        if (!loginStatus) {//没登陆,渲染当前页面
            return (
                <LoginWrapper>
                    <LoginBox>
                        <Input placeholder="账号" ref={(input) => { this.account = input }}></Input>
                        <Input placeholder="密码" type="password" ref={(input) => { this.password = input }}></Input>
                        <Button onClick={() => this.props.login(this.account, this.password)}>登录</Button>
                    </LoginBox>
                </LoginWrapper>
            )
        } else { //重定向到首页
            return <Redirect to="/" />    !!!!!! <Redirect to="/" />  的应用       
        }
    }
}
const mapStateToProps = (state) => ({
    loginStatus: state.getIn(["login", "login"])
})
const mapDispatchToProps = (dispatch) => ({
    login(accountElement, passwordElement) {
        dispatch(actionCreator.login(accountElement.value, passwordElement.value))
    }
})
export default connect(mapStateToProps, mapDispatchToProps)(Login);

盲点:import { Redirect } from "react-router-dom";新组件

修改header组件,点击"退出登录",修改login值

行为触发是在header/index.js
但数据修改是在login/store中
因此在header/index.js中,必须要引入login/store/actionCreator.js

import { actionCreator } from "./store";
import { actionCreator as loginActionCreator } from "../../pages/login/store";
//上面这句是用来修改login登录状态的,当前文件夹下的 actionCreator无法修改login
        {
          login ? <Navitem onClick={this.props.logout} className="right">退出登录</Navitem>:<Link to="/login"><Navitem className="right">登录</Navitem></Link>
        }
const mapStateToProps = (state) => {
    return {
        login:state.getIn(["login","login"])
    }
}
const mapDispatchToProps = (dispatch) => {
    return {
        logout() {
            dispatch(loginActionCreator.logout());
        }
    }
}
export default connect(mapStateToProps,mapDispatchToProps)(Header);
export const logout = () => ({
    type: actionType.LOGOUT,
    value:false
})
export default (state = defaultState, action) => {
  switch (action.type) {
    case actionType.LOGOUT:
      return state.set("login", action.value);
    default:
        return state;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值