• react-redux的使用


    https://www.jianshu.com/p/7a6708cde333

    安装:yarn add redux  react-redux --save

    redux分为三个部分组成action  reducer  store

    action可以触发reducer中的state   在改变共享状态的文件处使用

    const { dispatch } = this.props;   //使用connect后会生成dispatch

    dispatch(switchMenu(title));

    export const type = {
        SWITCH_MEUN: 'SWITCH_MEUN'
    }
    
    export function switchMenu(menuName) {
        console.log('menuName',menuName)
        return { // 这个返回的就是reducer中的action
            type:type.SWITCH_MEUN,
            menuName: menuName
        }
    }

    reducer是放置与改变共享状态值的地方 

     Reducer是生成store的方法createStore的参数,Reducer是一个方法,它接收两个参数state和action 

    state即当前组件间共享的数据,acion = {动作类别type,动作参数name}

    import { type } from '../action';
    const initialState = {
        menuName: '首页'
    }
    
    export default (state = initialState,action)=>{
        console.log('action',action) // 使用dispatch调用action中的方法会触发更新state 获取到action之后根据type的不同来更改不同的值    类似于action:{type: "SWITCH_MEUN", menuName: "订单管理"}
        switch (action.type) {
            case type.SWITCH_MEUN:
                return {
                    ...state, // 保存上一个状态值的写法
                    menuName:action.menuName
                }
                break;
            default:
                return {...state}
                break
    
        }
    }

     store.js

    // createStore是一个工厂方法,内里通过返回出去的方法作用于连保持了state(state就是共享数据)的生命
    // 并返回了一个包括三个方法的对象,三个方法分别为getState,subscribe,dispatch
    // getState即获取当前state也就是共享数据
    // subscribe接收一个方法为参数,目的是注册这个方法为dispatch调用后的callback方法
    // dispatch接收一个参数,这个参数是action = {动作类别, 动作参数}
    // dispatch内部调用了Reducer并在Reducer执行完毕后执行subscribe注册的callback(一般用于更新组件渲染)
    import { createStore } from "redux";
    import reducer from './../reducer';
    const configureStore=()=>createStore(reducer) //没有用大括号包着的代表返回的意思  Reducer传入craeteStore生成store
    export default configureStore //没有用大括号包着的代表返回的意思

    在根节点处引入store

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './public/css/index.css'
    import Route from './route'
    import { Provider } from 'react-redux'
    import configureStore from './redux/store/index.js';
    import * as serviceWorker from './public/js/serviceWorker';
    const store = configureStore(); //保存数据源的地方
    ReactDOM.render(
        // Provider是提供数据源的地方 Provider将所有要共享数据的组件共同的父组件包裹起来
        //     并作为含有context的高阶组件,同时将store传入,作为context共享的内容
        <Provider store={store}>
            <Route />
        </Provider>
       , document.getElementById('root'));
    
    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: https://bit.ly/CRA-PWA
    serviceWorker.unregister();

    使用共享状态的文件的使用

    import React from 'react'
    import {Row, Col} from 'antd'
    import '@/components/Header/index.less'
    import Unit from '../../unit/index'
    import Axios from '../../axios/index'
    import { connect } from "react-redux";
    
    class Header extends React.Component{
        constructor(props) {
            super(props)
            this.state = {
                systime : '',
                weather: '晴转多云',
                weather_pic: ''
            }
        }
        componentWillMount() {
            setInterval(()=>{
                let systime = Unit.formatetime(new Date().getTime())
                this.setState({
                    systime: systime
                })
            },1000)
           Axios.jsonp({url:'http://api.map.baidu.com/telematics/v3/weather?location=chengdu&output=json&ak=3p49MVra6urFRGOT9s8UBWr2'})
           .then((res)=>{
               this.setState({
                   weather: res.results[0].weather_data[0].weather,
                   weather_pic: res.results[0].weather_data[0].dayPictureUrl
               })
           }).catch((err)=>{
               console.log(err)
           })
            //  JsonP('http://api.map.baidu.com/telematics/v3/weather?location=chengdu&output=json&ak=3p49MVra6urFRGOT9s8UBWr2',{},function(err,data){
            //     console.log(data)
            // })
        }
        render() {
            return(
                <div className="header">
                    <Row className="header-top">
                        <Col span={24}>
                            <span>cjz管理后台</span>
                            <span href="#">退出</span>
                        </Col>
                    </Row>
                    <Row className="header-bottom">
                        <Col span={4} className="header-bottom-left">
                            <span>{this.props.menuName} </span>
                        </Col>
                        <Col span={20} className="header-bottom-right">
                            <span className="detail-time">{this.state.systime}</span>
                            <img className="weather-pic" src={this.state.weather_pic} alt=""/>
                            <span className="weather-detail">{this.state.weather}</span>
                        </Col>
                    </Row>
                </div>
            )
        }
    }
    const mapStateToProps = state => { //每个共享数据的组件都要通过mapStateToProps方法将state映射成自己可接收的props对象,之后通过this.props.menuName直接使用state中的值
        return {
            menuName: state.menuName
        }
    };
    export default connect(mapStateToProps)(Header); //第一个是接受回调方法  使用connect包裹Header组件

    改变共享状态的文件

    import React from 'react';
    import { Menu} from 'antd';
    import MeunList from '../../resource/navdata';
    import { connect } from "react-redux";
    import { switchMenu } from "../../redux/action";
    import '@/components/NavLeft/index.less';
    import { HashRouter, Link } from "react-router-dom";
    const { SubMenu } = Menu;
    class NavLeft extends React.Component {
        constructor(props) {
            super(props)
            this.state = {
                MenuNode: '',
                currentKey: ''
            }
        }
        componentWillMount() {
            const nodeTree = this.renderMenu(MeunList)
            var routeKey = window.location.hash.substr(1);
            this.setState({
                MenuNode: nodeTree
            })
        }
        renderMenu = (data) => {
            return data.map((item) => {
                if (item.children) {
                    return (
                        <SubMenu key={item.key} title={item.title}>
                           {this.renderMenu(item.children)}
                        </SubMenu>
                    )
                }
                return (
                    <Menu.Item key={item.key}> <Link to={item.key}>{item.title}</Link></Menu.Item>
                )
            })
        }
    
        handleClick = ({ item, key }) => {
            var title = item.props.children[1].props.children
            // 事件派发,自动调用reducer,通过reducer保存到store对象中
            const { dispatch } = this.props; //使用connect后会生成dispatch
            dispatch(switchMenu(title)); //使用dispatch调用action文件中的方法后会触发reducer中的方法,最终改变共享状态
    
        };
        render() {
            return (
                <HashRouter>
                    <div className="left-bar">
                        <div className="logo">Logo</div>
                        <div className="nav"></div>
                        <Menu theme='dark' onClick={this.handleClick} style={{  256 }} mode="vertical">
                            {this.state.MenuNode}
                        </Menu>
    
                    </div>
                </HashRouter>
            )
        }
    }
    export default connect()(NavLeft);

     如果需要异步修改状态值则需要安装thunk包 (此处为新增的内容)npm install redux-thunk redux-logger --save 

    定义的状态页面store.js

    import {createStore, applyMiddleware} from "redux"; // 引入中间件
    import logger from 'redux-logger' // 刚才新增的依赖
    import thunk from 'redux-thunk'
    const counterReducer = (state = 0, action) =>{
        switch (action.type) {
            case 'add':
                return state + 1
            case 'mines':
                return state - 1
            default:
                return state
        }
    }
    const store = createStore(counterReducer, applyMiddleware(logger, thunk)) // 这样就可以异步执行action修改值
    export default store;

    具体使用页面 page.js

    import React, {Component} from 'react';
    import {connect} from 'react-redux'
    
    class ReactReduxPage extends Component {
        constructor(props) {
            super(props);
        }
        render() {
            console.log(this.props)
            const {num, add, mines, asyAdd} = this.props
            return (
                <div>
                    <h1>reactReduxPage</h1>
                    <span>{num}</span>
                    <button onClick={() => add()}>+</button>
                    <button onClick={() => mines()}>-</button>
                    <button onClick={() => asyAdd()}>异步加</button>
                </div>
            );
        }
    }
    const mapStateToProps = state => { // 数据映射到props上
        return {
            num: state
        }
    }
    const mapDispatchToProps = { // 方法映射到props上
        add: () => {
            return {type: 'add'}
        },
        mines: () => {
            return {type: 'mines'}
        },
        asyAdd: () => dispatch => { // 异步修改数据
            setTimeout(() => {
                dispatch({type: 'add'})
            }, 1000)
        }
    }
    export default connect(mapStateToProps, mapDispatchToProps)(ReactReduxPage);
     
  • 相关阅读:
    Leetcode 40. Combination Sum II
    Leetcode** 39. Combination Sum
    Leetcode** 210. Course Schedule II
    Leetcode** 207. Course Schedule
    Leetcode 257. Binary Tree Paths
    Leetcode** 131. Palindrome Partitioning
    Leetcode** 20. Valid Parentheses
    Leetcode 14. Longest Common Prefix
    dfs序 二进制优化 Codeforces Round #316 (Div. 2)D. Tree Requests
    Codeforces Round #318 D. Bear and Blocks
  • 原文地址:https://www.cnblogs.com/cazj/p/11370266.html
Copyright © 2020-2023  润新知