React-Redux 在项目组是如何实现的
首先你要了解我们为啥要学习React-Redux
其实就是最主要的目的就是在react中非父子和之父组件的传递 还有就是为了缓存数据 减轻后端的压力 优化性能 其实就是减少了http的请求次数
下面我们来实现一下React-Redux 在真实项目中是如何实现的吧
首先来分析一下需求吧
实现点击按钮 完成侧边栏收缩效果 二个不同的组件 一个是header 组件 一个是sider组件
在点击实现交互效果
下面来看代码吧
**sider **
import React, { Component } from 'react'
import { Layout, Menu } from 'antd';
import MenuArr from '../../router/men';
import {connect} from 'react-redux'
import { withRouter } from 'react-router'
const { Sider } = Layout;
const { SubMenu } = Menu;
class SiderLeft extends Component {
//自己封装渲染函数 permission:'3', 权限管理等级
renderMenu = (menus)=>{
let { roleType } =JSON.parse(localStorage.getItem("token"))[0]
// console.log(roleType,menus)
return menus.map(item=>{
if(item.children){
// roleType =3
if(roleType<item.permission){
return null
}else{
return <SubMenu defaultSelectedKeys={['item.path']} key={item.path} title={
<span>
<item.icon/>
<span>{item.title}</span>
</span>
}>
{
//递归用法 在调用函数
this.renderMenu(item.children)
}
</SubMenu>
}
}else{
if(roleType<item.permission){
return null
}else{
return <Menu.Item defaultSelectedKeys={['11']} key={item.path} icon={<item.icon />}>
{item.title}
</Menu.Item>
}
}
})
}
handleChangePage = (obj)=>{
// console.log(obj.key)
// 高阶组件提供
this.props.history.push(obj.key)//key路由对应的路径
}
componentDidMount() {
}
componentWillUnmount(){
}
render() {
return (
<Sider trigger={null} collapsible collapsed={
this.props.Isshow // react-redux 中获取数据
}>
<div className="logo" />
<Menu
theme="dark" // 主题颜色
mode="inline" // 菜单类型
defaultSelectedKeys={['/home']} // 默认高亮效果 初始选中的菜单项 key 数组
// defaultOpenKeys={["/user-manage"]} // 初始展开的 SubMenu 菜单项 key 数组
onClick={this.handleChangePage} // 点击事件
>
{
this.renderMenu(MenuArr)
}
</Menu>
</Sider>
)
}
}
// connec拿到了store, store.getState()
const mapStateToProps = state => {
console.log(state.Isshow)
return {
Isshow:state.Isshow,
ISshowtopsider:state.ISshowtopsider
} //函数返回值 ,就是将来往sideMeun 组件传来的属性
}// 映射redux 状态==>当前组件属性
export default connect(mapStateToProps)(withRouter(SiderLeft))
header组件*
import React, { Component } from 'react'
import { Layout ,Avatar,Menu,Dropdown} from 'antd';
import { withRouter } from 'react-router';
import { changeIsshow } from "../../reduxs/action";
import {
MenuUnfoldOutlined,
MenuFoldOutlined,
UserOutlined
} from '@ant-design/icons';
import {connect} from 'react-redux'
const { Header } = Layout;
class Headertop extends Component {
state = {
// collapsed: false, // 用redux-react 处理
getuser:'',
homeIshow:true, // 显示隐藏
Isshow:true // header小箭头的开关
};
toggle = () => {
console.log("44444") // 在这里面发送信息 fasong
// console.log(this.props)
this.props.getisshowlick(changeIsshow(!this.state.Isshow))
this.setState({
// collapsed: !this.state.collapsed,
Isshow: !this.state.Isshow,
});
};
// 实现通过 数子去转换成文字的方法
rollName=()=>{
// var rollName=["小编","管理员","超级管理员"];
let rollName=this.state.getuser.roleType
// console.log(rollName)
//注意的是 === 先判断 的是类型 然后在判断 值是不是相等
if(rollName==="1"){
return <p style={{marginTop:"5px"}}>小编 </p>
}else if(rollName==="2"){
return <p style={{marginTop:"5px"}}>管理员</p>
}else{
return <p style={{marginTop:"5px"}}>超级管理员</p>
}
}
componentDidMount() {
let ues = JSON.parse(localStorage.getItem('token'))
this.setState({
getuser:ues[0]
}
guanli=()=>{console.log(1)} ;
//实现退出去到登录功能 需要引入高阶组件 withRouter
tuichu=()=>{
}
render() {
console.log(this.props);
const {
Isshow,
} = this.props;
console.log(Isshow)
const menu = (
<Menu onClick={(obj)=>{
if(obj.key==="a"){
console.log(1)
}else{
// 清楚token 跳转到login页面
localStorage.removeItem("token")
this.props.history.push('/login')
}
}}>
<Menu.Item key="a">
{
this.rollName()
}
</Menu.Item>
<Menu.Item key="b">
退出
</Menu.Item>
</Menu>
);
// let {getisshowlick} = this.props
// console.log(this.props,this.state)
return (
// 判断homeishow 是否为真 为真就在 不在就取消
// !Isshow ?
<Header className="site-layout-background" style={{ padding: "0 0 0 20px" }}>
{React.createElement(
this.props.Isshow // 控制小三角的改变
? MenuUnfoldOutlined
: MenuFoldOutlined, {
className: 'trigger',
onClick: this.toggle,
})}
{/* <h2> --- {count} </h2> */}
<span style={{float:"right",marginRight:"75px"}}>
欢迎 --{Isshow}<span style={{color:"red"}}>{this.state.getuser.username}</span>回来
</span>
<Dropdown overlay={menu}>
<Avatar size="large" icon={<UserOutlined />} />
</Dropdown>
</Header>
// :null
)
}
}
const mapStateToProps = state=>{
console.log(state)
return {
// homeIshow:state.ISshowtopsider,
Isshow: state.Isshow,
}
}
const mapDispatchToProps = {
change(obj){
return obj
},
getisshowlick(obj){ // 传递的函数
return obj
}
}
export default connect(mapStateToProps,mapDispatchToProps)(withRouter(Headertop))
组件确定后 我们来看看 redux
是怎么配置的
redux 的目录如上图 请原谅我用reduxs做redux 的文件名
分析一波吧
reducers 就是放reducer 的文件
来看一个吧
isshow.js
export const Isshow = (oldstate=true,action)=>{
let { type,payload } = action
switch (type) {
case "changeIsshow":
let newstate = payload // 深复制
return newstate
default:
return oldstate // 返回老的状态
}
}
action 如下
import axios from 'axios'
// 定义一个函数
// 控制全屏显示的 changeIsshow
export function changeIsshow(payload){
return {
type:"changeIsshow",
payload
}
}
来看看store.js
import {
createStore ,
applyMiddleware
} from "redux"
import { reducers } from "./reducers";
import thunk from "redux-thunk" // 中间件
import promise from "redux-promise" // 中间件
// applyMiddleware(thunk,promise)
const store = createStore(reducers,applyMiddleware(promise,thunk));
export default store;
总结一下吧:
-通过上面的图片我们能知道 点击小图标 完成组件传递信息 关闭侧边栏
下面分析流程
1 当点击事件触发时 onClick: this.toggle, 会触发事件 this.props.getisshowlick(changeIsshow(!this.state.Isshow))
会通过action 传递到store中 store 会传递(action 和oldstate)到 rducer (唯一修改state的地方)经过处理后会吧新数据传给store 然后store在传递给组件(sider接受)改变 Isshow 完成效果