参考地址:https://blog.csdn.net/q1056843325/article/details/54880804
使用:
(一)、首页js引入react-redux和store
import React from 'react'; import ReactDOM from 'react-dom'; import TodoList from "./TodoList"; import { Provider } from 'react-redux' import store from './store' const App = ( // Provider组件接受store做为props,子组件可以通过mapStateToProps方法里的state获取到stroe值 <Provider store={store}> <TodoList/> </Provider> ) ReactDOM.render( App, document.getElementById('root') );
(二)、配置stroe store/index.js
https://github.com/zalmoxisus/redux-devtools-extension
import { createStore, compose } from "redux";
import reducer from "./reducer";
// 配置以后就可以使用浏览器的react插件进行调试
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, composeEnhancers());
export default store;
(三)、TodoList.js
import React, { Component } from "react";
import HeaderCss from "./header.module.css";
import { CSSTransition } from "react-transition-group";
import { connect } from 'react-redux';
import { actionCreators } from './store';
class Header extends Component {
// eslint-disable-next-line no-useless-constructor
constructor(props) {
super(props);
}
render() {
return (
<div className={HeaderCss.header}>
<a className={HeaderCss.logo}/>
<div className={HeaderCss.nav}>
<div className={HeaderCss.navItem}>首页</div>
<div className={HeaderCss.navItem}>下载App</div>
<CSSTransition
in={this.props.focused}
timeout={200}
>
<div className={HeaderCss.inputDiv}>
<input
className={HeaderCss.input}
placeholder={'搜索'}
onFocus={this.props.handleInputFocus}
onBlur={this.props.handleInputBlur}
/>
</div>
</CSSTransition>
<div className={HeaderCss.navItem}>登录</div>
<div className={HeaderCss.navItem}>Aa</div>
</div>
<div className={HeaderCss.button}>登录</div>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
// 因为总的reducer.js里使用了combineReducers,所以state里的focused就变成了state下header里的focused
// 使用react插件可以看
// focused: state.header.focused
// reduce.js文件里使用immutable对state里的数据进行了封装
// state是js对象,header是immutable对象
// 为了统一,引入redux-immutable插件,都变成immutable对象
// focused: state.header.get('focused')
focused: state.get('header').get('focused')
// 还有一种写法
// focused: state.getIn(['header'], ['focused'])
}
}
const mapDispatchToProps = (dispatch) => {
return {
handleInputFocus () {
const action = actionCreators.searchFocus();
dispatch(action)
},
handleInputBlur () {
const action = actionCreators.searchBlur();
dispatch(action)
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Header);
(四)、reducer.js
使用combineReducers完成对数据的拆分管理(对reducer,js文件的优化)
在实际项目中,如果把所有的action都写在一个reducer.js文件里,会使得文件特别大,解决办法是在每个组件里定义单独的reducer.js文件,然后在总的reducer.js文件里,用combineReducers进行整合
例子:
一、header组件里创建store文件夹
reducer.js 用来存放header组件里相关的action
immutable https://github.com/immutable-js/immutable-js
import * as constants from './constants'
import { fromJS } from "immutable";
// 用fromJS把js对象转换成immutable对象
const defaultState = fromJS({
focused: false
});
export default (state = defaultState, action) => {
if (action.type === constants.SEARCH_FOCUS) {
// 这种写法要手动保证state的数据不被修改,比较麻烦
// 所以引入了immutable
// return {
// focused: true
// }
// immutable对象的set方法,会结合之前immutable对象的值
// 和设置的值,返回一个全新的对象
return state.set('focused', true)
}
if (action.type === constants.SEARCH_BLUR) {
// return {
// focused: false
// }
return state.set('focused', false)
}
return state;
}
index.js 用来导出reducer.js
import reducer from "./reducer"; export { reducer }
总的reducer.js文件
https://github.com/immutable-js/immutable-js
import { combineReducers } from "redux-immutable";
import { reducer as headerReducer } from '../common/header/store'
// 使用combineReducers整合单独组件的reducer数据
// 使用redux-immutable中的combineReducers,生成的就是immutable对象
export default combineReducers({
header: headerReducer
})