Redux状态管理与React-router

2019-03-08  本文已影响0人  陈裔松的技术博客

Redux状态管理

1,基本介绍
2,工作流
image.png
3,调试工具安装(可选,建议安装)
4,在React中使用Redux(以切换菜单为例)
// 文件:src/redux/action/index.js

// Action类型
export const type = {
    SWITCH_MENU:'SWITCH_MENU'
}

// Action函数
// 参数:用户点击的某个菜单名称
// 返回值:对象,包括事件类型和用户点击的菜单名称的对象
export function switchMenu(menuName){
    return{
        type:type.SWITCH_MENU,  // 事件类型
        menuName                // 菜单名称
    }
}
// 文件:src/redux/reducer/index.js

// 引入action类型
import { type } from './../action';

// 初始化state
const initialState = {
    menuName:'首页',
}

// 业务处理函数
// 参数1:状态(state),参数2:动作(action)
// 返回值:对象,是一个包括所有最新state的对象
export default (state = initialState, action) => {
    switch (action.type) {
        // 切换菜单
        case type.SWITCH_MENU:
            return {
                ...state,                 // 通过对象解构的方式保留原来的所有state
                menuName:action.menuName  // 更新menuName
            }
        default:
            return {
                ...state
            };
    }
} 
// 文件:src/redux/store/index.js

// 引入reducer
import reducer from './../reducer';

// 引入createStore。这是Redux中的一个方法,用于创建一个数据源对象,保存数据
import { createStore } from 'redux';

// 导出数据源
export default () => createStore(reducer)

如果已经安装调试工具redux-devtools-extension,这样写。可以用Redux Devtools清楚地看到redux状态的变化(如果出错了,就用上一种写法,比较保险)

// 文件:src/redux/store/index.js

// 引入reducer
import reducer from './../reducer';

// 引入createStore。这是Redux中的一个方法,用于创建一个数据源对象,保存数据
import { createStore } from 'redux';

// 引入调试工具redux-devtools-extension
import { composeWithDevTools } from 'redux-devtools-extension';

// 导出数据源,可以方便地看到state变化
export default () => createStore(reducer,composeWithDevTools())
// 文件:index.js

import { Provider } from 'react-redux';      // 引入Provider组件,用于提供数据源
import configureStore from './redux/store';  // 导入数据源创建方法
const store = configureStore();              // 创建数据源

// 用Provider组件包裹根组件Router,以提供数据源
// 这样Router里面的所有组件,都可以从数据源中获取数据
ReactDOM.render(
    <Provider store={store}>
        <Router />
    </Provider>,
    document.getElementById('root'));
import { connect } from 'react-redux';              // 引入react-redux的connect方法
import { switchMenu } from './../../redux/action';  // 引入已经定义好的action

class Sidebar extends React.Component {
    // ...省略...
    currentTitleManage = () => {
        // ...省略...
        this.props.dispatch(switchMenu(currentTitle));  // 触发switchMenu动作
        // ...省略...
    }
    // ...省略...
}

// 通过connect方法连接Sidebar组件和redux
export default connect()(Sidebar);

取得redux的状态

import { connect } from 'react-redux';

class Header extends React.Component {
    // ...省略...
    {this.props.menuName}  // 取得菜单名称
    // ...省略...
}

// 获取数据源
const mapStateToProps = state => {
    return {
        menuName: state.menuName
    }
}

// 通过connect方法连接Header组件和redux
export default connect(mapStateToProps)(Header);

React-router

1,react-router和react-router-dom理解
2,react-router-dom核心用法
    // path:路径,component:路径对应的组件
    <Route path="/login" component={Login}/>

    // render:添加子路由
    // exact:精准匹配
    <Route path='/' render={()=>
        this.props.logout ? 
        (
            <Redirect to={`/login`}/>
        ) :
        (
            <Admin>
                <Switch>
                    <Route path="/home" component={Home}/>
                    <Route exact path='/contracts/list' component={ContractList}/>
                    ...
// NavLink:主要用于菜单导航

import { NavLink } from 'react-router-dom';

    // 第一种写法:to地址
    <NavLink to='/home' replace>
        <span>首页</span>
    </NavLink>

    // 第二种写法:to对象,对象里包含一个pathname属性
    <NavLink to={pathname:'/home'} replace>
        <span>首页</span>
    </NavLink>

    // 第三种写法:to对象,对象里包含比较多的属性
    <NavLink to={pathname:'/home',search:'',hash:'',key:'123',state:{}} replace>
        <span>首页</span>
    </NavLink>
// Link:主要用于链接
// 用法与NavLink一致
// 单个路由匹配:如果匹配到一个路由,就结束匹配
    <Switch>
        <Route path="/home" component={Home}/>
        <Route path='/contracts/list/add' component={ContractListDetail}/>
        <Route path='/contracts/list/edit/:id' component={ContractListDetail}/>
    </Switch>
// 路由重定向

<Redirect to='/login'/>  // 重定向到login
// "/home"是"/"下的子路由,需要用render的形式

<Route path='/' render={()=>
    <Admin>
        <Switch>
            <Route path="/home" component={Home}/>
        </Switch>
    </Admin>
}/>
// Admin组件

export default class Admin extends React.Component{
    render() {
        return (
            <Layout style={{ minHeight: '100vh' }}>
                <Sidebar/>
                <Layout>
                    <Header/>
                    <Content style={{ padding: '10px 10px 0'}}>
                        {this.props.children}  // 这里就是各个子路由对应的组件
                    </Content>
                    <Footer/>
                </Layout>
            </Layout>
        );
    }
}
上一篇 下一篇

猜你喜欢

热点阅读