第一步创建项目:这里我直接采用dva创建项目
dva new react_five
创建后,通过webstore打开项目,项目解构大概如下:
第二步:创建几个文件夹。
第三步:修改src/router.js文件
before:
import React from 'react';
import { Router, Route } from 'dva/router';
import IndexPage from './routes/IndexPage';
function RouterConfig({ history }) {
return (
"/" component={IndexPage} />
);
}
export default RouterConfig;
dva默认访问的是/routes/IndexPage文件,我们这里需要修改成,访问/containers/App.jsx ,并且我们需要修改组件调用处的代码,需要将store对象传给组件
after:
import React from 'react';
import { Router, Route } from 'dva/router';
import IndexPage from './routes/IndexPage';
import { Provider } from 'react-redux';
import App from './containers/App'
//通过一个store的配置文件来初始化store对象
import configureStore from './stores/configureStore';
const store = configureStore();
function RouterConfig({ history }) {
return (
//Provider是redux组件提供的一个系统方法
"/" component={App} />
);
}
export default RouterConfig;
修改完了,最好是写个简单的App.jsx启动下服务看看,如果等全部写完再来调试,碰到问题就比较难查找了。
第四步:定义store的配置信息
其实我们在修改入口的方法时,我们通过configureStore创建了一个store对象
import configureStore from './stores/configureStore';
const store = configureStore();
然后通过Provider 将store对象传给了组件App的上下文。
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App} />
Router>
Provider>
所以需要我们来定义configureStore的内容
/stores/configureStore.js的内容如下:
import { createStore } from 'redux';
import rootReducer from '../reducers';
export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState);
if (module.hot) {
module.hot.accept('../reducers', () => {
const nextReducer = require('../reducers');
store.replaceReducer(nextReducer);
});
}
return store;
}
他从 redux 拿到 createStore 这个函数,再获取到 rootReducer ;
createStore 函数接收两个参数,(reducer, [initialState]),reducer 毋庸置疑,他需要从 store 获取 state,以及连接到 reducer 交互。
initialState 是可以自定义的一个初始化 state,可选参数。
module.hot这个可以不用管,这是 webpack 热加载的处理,你也可以不要他。
第五步:定义reducer,因为第四步里面有个关键语句
const store = createStore(rootReducer, initialState);
所以我们来定义reducer的内容, /reducers/index.js 的内容如下:
import { combineReducers } from 'redux';
import ClickButton from './ClickButton';
//combineReducers的作用就是将多个reducer合并成一个reducer。这里这么写是为了后期方便进行扩展。
const rootReducer = combineReducers({
ClickButton
});
export default rootReducer;
reducers/ClickButton.js的内容如下:
import {
CHANGE_TEXT,
CLICK_BUTTON
} from '../actions';
const initialState = {
text: 'Hello'
}
function clickRedux(state = initialState, action) {
switch (action.type) {
case CHANGE_TEXT:
return {
text: action.text
}
case CLICK_BUTTON:
return {
text: action.text
}
default:
return state
}
}
export default clickRedux;
第六步:添加actions信息:我们在定义reducer时其实我们反复的看到了action对象,所以我们需要来定义的相应的action。其实action你可以定义为行为,根据不同的行为指定不同的Type,然后reducer再根据不同的Type来获取不同的数据信息。
/actions/index.js的内容如下:
export const CHANGE_TEXT = 'ADD_TODO';
export const CLICK_BUTTON = 'COMPLETE_TODO';
export function ChangeText() {
return {
type: CHANGE_TEXT,
text:"点击了ChangeText"
};
}
export function ClickButton() {
return {
type: CLICK_BUTTON,
text:"点击了ClickButton"
};
}
第七部:回到containers/App.jsx界面入口处,修改其中的代码:
import React,{Component} from 'react';
import {connect } from 'react-redux';
import {
ChangeText,
ClickButton
} from '../actions';
class App extends Component{
render(){
const {dispatch,text} = this.props;
return (
dispatch(ChangeText())}> {text}
);
}
}
//映射Redux state到组件的属性s
function mapStateToProps(state) {
console.log(state.ClickBox.text)
return { text:state.ClickBox.text}
}
export default connect(mapStateToProps)(App)
通过npm start启动起来,浏览器中效果如下
点击按钮:界面变成如下:
点击字,界面如下:
下节我们对上面的代码进行分析,这节我们只是把功能实现了而已