React-redux相关依赖
- yarn add redux react-redux react-thunk redux-devtools-extension
- npm i redux react-redux react-thunk redux-devtools-extension
- cnpm i redux react-redux react-thunk redux-devtools-extension1
对应文件的配置
- store.js
// 核心管理者——数据仓库
// createStore创建核心store对象,applyMiddleware注册插件
import { createStore, applyMiddleware } from 'redux'
// 引入reducer,若文件夹中需要引入的是index文件则可以省略,直接写文件夹名字
import reducers from './reducers'
// 引入redux-thunk,异步中间键,使action可以执行异步代码
import thunk from 'redux-thunk'
// 引入redux-devtools-extension,用于支持redux开发者调试工具的运行(一个谷歌可视化插件,文末附下载方式)
import { composeWithDevTools } from 'redux-devtools-extension'
// 全局导出
export default createStore(reducers, composeWithDevTools(applyMiddleware(thunk)))
- action_types.js
//防止写错action名字,该文件可以没有,不是必须的
// js常量大写字母命名
export const GET_LOGIN_INFO = 'get_Login_Info'
- loginInfoAction.js
import { GET_LOGIN_INFO } from '../action-type'
export const getLoginInfo = value => ({ type: GET_LOGIN_INFO, data: value })
- loginReducer.js
import { GET_LOGIN_INFO } from '../action-type'
let initUserInfo = {
token: '',
user: {},
isLogin: false,
}
export default function LoginReducer(preState = initUserInfo, action) {
const { type, data } = action
let newState
switch (type) {
case GET_LOGIN_INFO:
newState = { user: data.user, token: data.token, isLogin: true }
return newState
default:
return preState
}
}
- recuderIndex.js
import { combineReducers } from 'redux'
import loginInfoRecuder from './loginReducer'
export default combineReducers({
userInfo: loginInfoRecuder,
})
6.需要在index.js中
import React from 'react'
import ReactDOM from 'react-dom'
import store from './redux/store'
import { Provider } from 'react-redux'
import './index.css'
import App from './App'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
- login.js 登录组件做举例,进行UI组件和容器组件融合
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Form, Input, Button, message } from 'antd'
import { UserOutlined, LockOutlined } from '@ant-design/icons'
import { reqLogin } from '../../api'
import { getLoginInfo } from '../../redux/action/loginInfoAction'
import logo from '../../assets/images/logo.png'
import './index.css'
@connect(state => ({}), {
saveUserInfo: getLoginInfo,
})
class LoginComponent extends Component {
handleSubmit = async values => {
const { username, password } = values
const { data, status } = await reqLogin(username, password)
console.log(data, status)
if (status === 0) {
// 1.请求到的值保存到redux
this.props.saveUserInfo(data)
// 2.跳转,必须在存储之后跳转否则跳转到的组件拿不到值
this.props.history.replace('/admin')
message.success('登录成功!')
} else {
message.error(data.msg)
}
// this.props.loginAsync(username, password)
}
/*
对密码进行自定义验证
*/
validatePwd = (rule, value, callback) => {
const pwdReg = /^[a-zA-Z0-9_]+$/
const length = value && value.length
/*
用户名/密码的的合法性要求
1). 必须输入
2). 必须大于等于4位
3). 必须小于等于12位
4). 必须是英文、数字或下划线组成
*/
if (!value) {
return Promise.reject('密码必须输入')
} else if (length < 4) {
return Promise.reject('密码必须大于等于4位')
} else if (length > 12) {
return Promise.reject('密码必须小于等于12位')
} else if (!pwdReg.test(value)) {
return Promise.reject('密码必须是英文、数字或下划线组成')
} else {
return Promise.resolve() // 验证通过/成功
}
}
render() {
return (
<div className="login">
<div className="login-header">
<img src={logo} alt="login" />
<h1>商城管理系统</h1>
</div>
<div className="login-content">
<h1>用户登录</h1>
<Form
name="normal_login"
className="login-form"
initialValues={{
remember: true,
}}
onFinish={this.handleSubmit}
>
<Form.Item
name="username"
// 配置对象
initialValue="" // 初始值
/*
用户名/密码的的合法性要求
1). 必须输入
2). 必须大于等于4位
3). 必须小于等于12位
4). 必须是英文、数字或下划线组成
*/
// 声明式验证: 利用已有的验证规则进行验证, 不用亲自判断
rules={[
{ required: true, whitespace: true, message: '用户名必须输入' },
{ min: 4, message: '用户名不能小于4位' },
{ max: 12, message: '用户名不能大于12位' },
{ pattern: /^[a-zA-Z0-9_]+$/, message: '用户名必须是英文、数字或下划线组成' },
]}
hasFeedback
>
<Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="用户名" allowClear />
</Form.Item>
<Form.Item
name="password"
// 初始值
initialValue=""
rules={[
// 自定义验证
{ validator: this.validatePwd },
]}
hasFeedback
>
<Input.Password prefix={<LockOutlined className="site-form-item-icon" />} type="password" allowClear placeholder="密码" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" color="#1DA57A" className="login-form-button">
登录
</Button>
</Form.Item>
</Form>
</div>
</div>
)
}
}
export default LoginComponent
8.admin中拿到login组件存储到redux的值
import React, { Component } from 'react'
import { connect } from 'react-redux'
import './admin.css'
@connect(state => ({ userInfo: state.userInfo }), {})
class Admin extends Component {
render() {
console.log(this.props.userInfo)
return (
<div>
<h1>欢迎{this.props.userInfo && this.props.userInfo.user.username}</h1>
</div>
)
}
}
export default Admin