React生态之Redux

Redux 基本介绍

State:React中的状态是制度对象,不可直接修改
Reducer:基本函数,用于对State的业务处理
Action:普通对象,用于描述事件行为,改变State
Redux 解决单项数据流的问题 , 项目中共享全局数据

Redux 工作流

在这里插入图片描述

Redux 安装
  • npm 安装

    npm install redux --save
    npm install react-redux --save

  • yran 安装

    yarn add redux
    yarn add react-redux

Redux 调试工具安装
  • 浏览器安装Redux Devtools扩展
  • npm install redux-devtools-extension --save
  • yarn add redux-devtools-extension
Redex 集成

创建Action模块
创建Reducer模块
创建Store模块
通过connect方法将React组件和Redux连接起来
添加Provider作为项目的跟组件,用于数据的存储

Redux 集成具体操作步骤
  1. 在Action中定义index.js
	/**
	 * Action 类型
	 */
	//定义类型名
	//第2种方式.这里可以在外部定义type的所有内容 例如:import { SWITCH_MENU } from "./type";
	export const type={
	    SWITCH_MENU:'SWITCH_MENU',
	}
	//触发操作方法就像Vuex的mutations的方法,menuName就是修改的名称 type.类型名称固定定义方式
	export function switchMenu(menuName) {
	    return{
	        type:type.SWITCH_MENU, //第2种方式 : type:SWITCH_MENU,
	        menuName
	    }
	}
  1. Reducer 中定义index.js
	/**
	 * Reducer 数据处理
	 */
	 
	import {type} from "./../action";
	//初始化常量状态
	const initialState = {
	    menuName: '首页'
	}
	//值的修改操作在这里进行
	export default (state = initialState, action) => {
		//这里可以做类型判断可以进行多个值的操作
	    switch (action.type) {
	    	//判断传入值的类型,如果时候menu则赋值action.menuName
	        case type.SWITCH_MENU:
	            return{
	                ...state,//原来的值,不能清空原有的值。因为数据内可能还有别的数据以免误操
	                menuName: action.menuName//新的值
	            }
	            break;
	        default:
	        	return state;//没有任何设置的数据的时候这里要返回state的默认值,否则系统找不到初始数据报错。也可以在mapStateToProps 内部做初始化数据定义,但一定要有初始化的数据
	            break;
	    }
	}
  1. store中定义index.js
	/**
	 *  引入creatStore 创建store
	 */
	 //创建store工厂
	import {createStore} from 'redux'
	//引入reducer 业务处理方法
	import reducer from '../reducer'
	//devtools 调试工具使用
	import {composeWithDevTools} from 'redux-devtools-extension'
	//导出新创建的数据源(第一个参数是reducer方法,4.0以后版本不能使用第二个参数可以是调试工具的插件方法)
	//export default ()=>createStore(reducer,composeWithDevTools())
	export default ()=>createStore(reducer)
  1. 入口文件index.js 中创建根组件
	import React from 'react';
	import ReactDOM from 'react-dom';
	import './index.css';
	import Route from './router'
	//提供数据源
	import {Provider} from 'react-redux'
	import configStore from './redux/store'
	import * as serviceWorker from './serviceWorker';
	
	const store=configStore()
	ReactDOM.render(
		//Provider组件包裹根组件,并且传入store数据源对象,也可以在组建中包裹
	    <Provider store={store}>
	        <Route/>
	    </Provider>
	    ,document.getElementById('root')
	);
	serviceWorker.unregister();

  1. 组件页面连接Redux,修改数据
	import React from 'react'
	import './index.less'
	import {Menu, Icon, Switch} from 'antd';
	import {NavLink} from 'react-router-dom'
	//导入连接方法和action方法
	import {connect} from 'react-redux'
	import {switchMenu} from './../../redux/action'
	
	import MenuConfig from '../../config/menuConfig'
	
	const {SubMenu} = Menu;
	
	class NavLeft extends React.Component {
	    constructor() {
	        super()
	        this.state = ({
	            theme: 'dark'
	        })
	    }
	
	    componentWillMount() {
	        const menuTreeNode = this.renderMenu(MenuConfig)
	        this.setState({
	            menuTreeNode
	        })
	    }
		
	    handleClick = (item) => {
	    	//使用dispatch 修改数据
	        const {dispatch} = this.props
	        dispatch(switchMenu(item.item.props.title))
	
	        // console.log(item.item.props.title)
	    }
	
	    renderMenu = (data) => {
	        if (!data) return false
	        return data.map((item) => {
	            if (item.children) {
	                return (
	                    <SubMenu title={item.title} key={item.key}>
	                        {this.renderMenu(item.children)}
	                    </SubMenu>
	                )
	            }
	            return (
	                <Menu.Item title={item.title} key={item.key}>
	                    <NavLink to={item.key}>{item.title}</NavLink>
	                </Menu.Item>
	            )
	        })
	    }
	
	    render() {
	        return (
	            <div className="nav-left-wrap">
	                <div className="left-logo">
	                    这是logo
	                </div>
	                <div>
	                    <Menu
	                        onClick={this.handleClick}
	                        // mode={this.state.mode}
	                        theme={this.state.theme}
	                    >
	                        {this.state.menuTreeNode}
	                    </Menu>
	                </div>
	            </div>
	        )
	    }
	}
	//这里把Redux和组件连接起来导出
	export default connect()(NavLeft)
  1. 调用数据
	import React from 'react'
	import {Row, Col} from 'antd'
	import './index.less'
	import Utils from '../../utils/utils'
	import axios from '../../axios'
	import {connect} from 'react-redux'
	
	 class Header extends React.Component {
	    constructor() {
	        super()
	        this.state = ({
	            username: '在水一方'
	        })
	    }
	
	    componentWillMount() {
	        setInterval(() => {
	            let sysTime = Utils.formateDate(new Date().getTime())
	            this.setState({
	                sysTime: sysTime
	            })
	        }, 1000)
	        this.getWeatherApiData();
	    }
	
	    getWeatherApiData() {
	        let city = '北京'
	        let url = "http://api.map.baidu.com/telematics/v3/weather?location=" + encodeURIComponent(city) + "&output=json&ak=UjymBYD3091SXF9ZW5FwpDlG"
	        axios.jsonp({
	            url: url
	        }).then((res) => {
	            let weather = res.results[0].weather_data[0]
	            console.log(weather)
	            this.setState({
	                dayPictureUrl: weather.dayPictureUrl,
	                weather: weather.weather
	            })
	        })
	    }
	
	    render() {
	        return (
	            <div className="header-wrap">
	                <Row className="header-top">
	                    <Col span={24}>
	                        <span>欢迎, {this.state.username}</span>
	                        <a href="#"> 退出</a>
	                    </Col>
	                </Row>
	                <Row className="breadcrumb">
	                    <Col className="bread-title" span={4}>
	                        {/*调用数据*/}
	                        {this.props.menuName}
	                    </Col>
	                    <Col className="bread-weather" span={20}>
	                        <span>{this.state.sysTime}</span>
	                        <span>
	                            <img src={this.state.dayPictureUrl} alt=""/>
	                            <span>{this.state.weather}</span>
	                        </span>
	                    </Col>
	                </Row>
	            </div>
	        )
	    }
	}
	// 导出数据导到组件中
	const mapStateToProps = state => {
		console.log(state)//这里是返回的{menuName:内容对象} 
	    return {
	        menuName: state.menuName
	    }
	}
	
	export default connect(mapStateToProps)(Header)
发布了156 篇原创文章 · 获赞 531 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_39043923/article/details/88841911