demo 简介
通过组件的事件改变 store 中的 state 值,进而改变视图,同时通过调用接口来渲染数据。地址:https://github.com/MaTonna/demoForRedux
使用的依赖
- react-redux:管理 react 当中的 state,创建一个集中管理的 store
- redux-thunk: redux 的中间件,使 action 返回一个函数,组件派发事件时可以做一些处理
- axios:HTTP 库,创建 http 请求
- immutable|redux-immutable: 用于返回新的 state,在 reducer 中用到(不允许修改传递过来的 state)
- styled-components:写组件样式的库,把每个元素当作组件来写,方便统一组件样式
目录结构
redux flow 思路
创建 store,整合 reducer
- 在入口 index.js 内引入 APP.js 和用 styled-components 创建的 reset.css
//index.js中
import { GlobalStyle } from './style';
ReactDOM.render(
<App>
<GlobalStyle />
</App>,
document.getElementById('root')
);
// style.js
import { createGlobalStyle } from 'styled-components';
export const GlobalStyle = createGlobalStyle`reset.css的内容`
- 在 store.js 中引入 redux-thunk 作为中间件,在创建 store 时,加入 reducer 来处理 action
import { createStore, compose, applyMiddleware } from 'redux';
import reducer from './reducer';
import thunk from 'redux-thunk';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)));
export default store;
- 在统一的 reducer 中使用 redux-immutable 的 combineReducers 来整合各个组件的 reducer
import { combineReducers } from 'redux-immutable';
import { reducer as headerReducer } from '../common/header/store';
export default combineReducers({
header: headerReducer
});
- 在 APP.js 内引入 store, 使用 react-redux 的 Provider 将 state 传入组件
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import Header from './common/header';
import store from './store';
class App extends Component {
render() {
return (
<Provider store={store}>
<Header />
</Provider>
);
}
}
export default App;
在组件中创建自己的 reducer,并派发 action
- 创建组件自己的 reducer 和 actionCreator
//reducer.js
import { fromJS } from 'immutable';
// 转化为immutable类型数据
const defaultState = fromJS({
focused: false
});
// 默认导出一个函数,接收state和action作为参数
export default (state = defaultState, action) => {
//通过接收action.type,来定义不同action的处理方式,例如:
if(action.type === 'SEARCH_FOCUS') {
//改变state的值并返回一个新的state,触发了组件里的props的变化
return state.set('focused', true);
}
return state;
}
};
//actionCreator.js
import axios from 'axios';
import { fromJS } from 'immutable';
export const searchFocus = () => ({
type: 'SEARCH_FOCUS'
});
- 在组件中使用 react-redux 中的 connect 连接 APP.js 的 store,connect 中传入 mapStateToProps 和 mapDispatchToProps,作用分别为映射 store 中的 state 到组件的 props 里,和派发事件的 action
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { HearderWrapper, SearchInput } from './style';
//store的index.js中export { reducer, actionCreators }
import { actionCreators } from './store';
class Hearder extends Component {
render() {
const { focused, handlerInputFocus, handlerInputBlur } = this.props;
return (
<HearderWrapper>
//使用connect做了一个绑定
//这里的this.props.handlerInputFocus/focused就是mapDispatchToProps里的handlerInputFocus/focused
<SearchInput className={focused ? 'focus' : 'blur'} onFocus={handlerInputFocus}/>
</HearderWrapper>
);
}
}
const mapStateToProps = state => {
return {
focused: state.getIn(['header', 'focused']),
};
};
const mapDispatchToProps = dispatch => {
return {
//发生事件时派发actionCreator
handlerInputFocus() {
dispatch(actionCreators.searchFocus());
}
};
};
// 容器组件-负责处理数据逻辑
export default connect(
mapStateToProps,
mapDispatchToProps
)(Hearder);