React-Redux初实践

3 篇文章 0 订阅
1 篇文章 0 订阅

这礼拜终于把手头的需求完结的差不多了,终于有时间沉淀下这段时间学习到的新技术了。

redux,我是在阮一峰大神的教程里学习的,先粘上传送门,大神在3篇连续的教程中,很详细的讲解了redux和React-Redux 的原理和用法,而我接下来主要是整理下我的学习笔记,和我在实践中走过的坑。

一.我对redux理解

众所周知,用react去做页面逻辑的时候,页面所见的所有dom元素,都可以被拆分成小的组件,如果遇到复杂页面,层级结构较多的话,组件state状态的统一管理就会很费劲,redux就是把页面所有需要共享的状态统一管理,存储到一个对象当中,如果在一个组件内部改变了这个state,那么所有组件用到这个state的地方都会随之做出改变,做到牵一发而动全身,不过要提醒大家一点注意的是,如果正如阮一峰大神的写在前言,对于简单的路由页面,是没有必要一定用redux来管理state的。

二.我的redux实践

在这里我举个简单栗子,就像我在做的控制台,整个项目用的react-router前端路由,所有子页面都是组件,左边是整体导航,右边是路由子页面,当用户切换右边tab页面的时候,父级组件的menu需要做高亮联动,之前这里实现,我是用prop-types库,祖先传参的方法实现的(具体实现参见上篇),这里用了redux管理状态的话,就会很简单的实现这个需求。

1.安装

cnpm install redux --save-dev

cnpm install react-redux --save-dev

cnpm install prop-types --save-dev

2.首先,需要在入口index.js即入口文件,创建全局的store存储状态对象,Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了。

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
//React-Redux 提供Provider组件,可以让容器组件拿到state。
//它的原理是React组件的context属性
import { Provider } from 'react-redux';
// import './index.css';
import App from './template/App';
import registerServiceWorker from './registerServiceWorker';
//Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入createStore方法
import reducers from './reducers/index';

// console.log(createStore)
//Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
const store = createStore(reducers);
const rootEl = document.getElementById('root');

// ReactDOM.render(<App />, document.getElementById('root'));
const render = () => ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootEl
);

render();
registerServiceWorker();
//设置监听函数,一旦 State 发生变化,就自动执行这个函数。
store.subscribe(render);

3.创建reducer处理器

我所理解的reducer就是一个switch处理器,根据不同的输入态,返回对应的输出态。

src/reducers/index.js

import { combineReducers } from 'redux'
import menuSwitch from './menuSwitch'
import counter from './counter'

const reducers = combineReducers({
	menuSwitch: menuSwitch,
	counter1: counter,
});

export default reducers

src/reducers/menuSwitch.js

const defaultState = 'containerTaskList';
const menuSwitch = (state = defaultState, action) => {
  switch (action.type) {
  case 'MENU_1':
    return 'containerTaskList'
  case 'MENU_2':
    return 'containerContainerList'
  default:
    return state
  }
}

export default menuSwitch

4.子页面逻辑

src/template/workshop/laboratory/Lab5.js

在子页面中,如此改变menu菜单的state

store.dispatch({ type: 'MENU_2' });

5.父页面逻辑

src/template/framework.js

在父级framework里的render函数里,用store.getState就可以获得改变的菜单state

render() {
	let currentMenu1 = this.context.store.getState().menuSwitch;
	return (
		<Menu 
		    selectedKeys={[currentMenu]}
		</Menu>
	)
}

三.踩坑

在react-router路由中,需要把路由配置部分单独提出来,不然会有如下报错,虽然是个warning,但是很烦人有木有啊!!

这里当真是折腾了我整整一晚上,才在Stack Overflow上找到了解决方案,新改后的路由配置部分如下,把routes单独提取到变量当中,并且把initFrameWork方法也单独提取出来了,不知道react-router4里有没有改进这个问题。

app.js

const initFrameWork = (nextState, replace, cb) =>{
	//blabla
};


const routes = (
    <Route path="/">
        {/*重定向 到myHome*/}
        <IndexRedirect to="/index" />
        {/*登录*/}
        <Route path="/login" getComponent={$util.lazyLoadComponent(require('./Login'))}></Route>


        {/*主框架*/}
        <Route path="/frameWork" getComponent={$util.lazyLoadComponent(require('./FrameWork'))} onEnter={initFrameWork}>
    </Route>
)


class App extends Component {
    state = {
    };
    render() {
        return (
            <Router history={browserHistory}>
                { routes }
            </Router>
        );
    }
}	//blabla
};


const routes = (
    <Route path="/">
        {/*重定向 到myHome*/}
        <IndexRedirect to="/index" />
        {/*登录*/}
        <Route path="/login" getComponent={$util.lazyLoadComponent(require('./Login'))}></Route>


        {/*主框架*/}
        <Route path="/frameWork" getComponent={$util.lazyLoadComponent(require('./FrameWork'))} onEnter={initFrameWork}>
    </Route>
)


class App extends Component {
    state = {
    };
    render() {
        return (
            <Router history={browserHistory}>
                { routes }
            </Router>
        );
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值