文件目录
*---store // 存放redux,数据,以及action
*---store子目录
actions // 存放action的文件夹
reducers // 存放reducer的文件夹
actionTypes.js // 存放所有的actionType
index.js // store的入口文件
安装
npm install redux react-redux -S
cnpm install redux react-redux -S
yarn add redux react-redux -S
使用
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
ReactDOM.render(
<Provider>
<App />
</Provider>,
document.getElementById('root')
);
import { createStore, combineReducers } from 'redux';
// createStore方法是用来创建store的,combineReducers方法是用来合并多个reducer的
// 创建根reducer,利用combineReducers合并多个reducer,此处还未定义reducer,所以暂空
const rootReducer = combineReducers({
})
// 创建初始化的state,初始化为一个空对象即可,默认的数据建议都写在reducer上
const initializeState = {}; // 定义初始化的state
// 创建store,第一个参数是根reducer,第二个参数可以是初始化的state,也可以是别的,暂且不提
const store = createStore(rootReducer,initializeState);
// 抛出store
export default store;
/**之前的代码**/
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
// 定义初始化的数据,根据实际数据即可
const initializeState = {
count: 1
}
// 定义reducer,第一个参数为state,赋予默认值为上边定义的initializeState,
// 第二个参数为action,并return一个state
// 并且抛出这个countReducer
export default function countReducer(state = initializeState,action) {
return state;
}
// 引入countReducer,
import countReducer from './reducers/countReducer';
// 将countReducer合并到rootReducer上,并使用原有名称
const rootReducer = combineReducers({
countReducer
})
// 也可以给countReducer改名,如下,改名成为count
const rootReducer = combineReducers({
count: countReducer
})
接着只需要将组件改造一下,就可以使用reducer上边的数据了
在src/APP.js中,或者是你需要使用store中数据的组件中,引入react-redux提供的connect方法
import { connect } from 'react-redux';
并且在抛出之前,定义获取数据的方法mapStateToProps
// 定义方法mapStateToProps,参数为state,并且返回一个对象,对象内定义需要获取的store内的数据,
// 由于是使用的countReducer中的数据,所以需要使用state.countReducer.属性名
function mapStateToProps(state) {
return {
count: state.countReducer.count
}
}
接着,在抛出的时候调用connect方法改造当前组件
// connect的第一个参数为数据,即mapStateToProps方法
// 接着在第二个括号内传入当前需要被改造的组件
export default connect(mapStateToProps)(App);
class App extends Component {
render() {
return (
<div>
{this.props.count}
</div>
);
}
}
获取到数据之后,接着应该是修改仓库内的数据
修改数据首先需要定义一个dispatch,在redux中,修改数据必须通过dispatch提交一个action来进行,在src/store/actions目录下新建countAction.js
在countAction.js中定义addCount方法,并return一个对象,对象上有一个type属性,这个属性对应的是一个常量字符串,这个字符串定义在src/store/actionTypes.js中,主要是为了可以公共的管理,因为同一个常量需要在两个地方使用
// countAction.js
import { ADD_COUNT } from '../actionTypes'
export function addCount() {
return {
type: ADD_COUNT
}
}
// actionTypes.js
export const ADD_COUNT = 'ADD_COUNT';
import { ADD_COUNT } from '../actionTypes';
export default function countReducer(state = initializeState,action) {
switch (action.type) {
case ADD_COUNT:
return { count: state.count + 1 };
default:
return state;
}
}
紧接着,要在组件中使用这个addCount方法,提交这个dispatch,触发这个action
在App.js或者是使用store的组件中,首先引入addCount方法,然后在mapStateToProps的下边,在定义一个mapActionToProps方法,接着在connect的第二个参数位置,传入这个方法即可
在mapActionToProps方法中,第一个参数为dispatch,return一个对象,对象上定义方法
方法名自定义即可,接着触发这个方法的时候,触发dispatch(),并传入引入的addCount()方法,需要加括号调用,因为只有调用才会返回一个对象,( 或者addCount直接是一个对象,而不是一个函数 )
import { addCount } from './store/actions/countAction'
/** 其余代码 **/
/** mapStateToProps **/
function mapActionToProps(dispatch) {
return {
addCount: () => dispatch(addCount())
}
}
export default connect(mapStateToProps,mapActionToProps)(App);
此时,可以在App组件内调用this.props.addCount()方法来修改store中的数据了
当然,但凡是方法,都可以传参,
首先在src/store/actions/countAction.js中定义一个新的方法,
当然,这个方法用到的REDUCE_COUNT常量要定义在src/store/actionTypes.js中
// src/store/actions/countAction.js
export function reduceCount(num) {
return {
type: REDUCE_COUNT,
num
}
}
// src/store/actionTypes.js
export const REDUCE_COUNT = 'REDUCE_COUNT';
// src/store/reducers/countReducer.js
import { ADD_COUNT, REDUCE_COUNT } from '../actionTypes'
export default function countReducer(state = initializeState,action) {
switch (action.type) {
case ADD_COUNT:
return { count: state.count + 1 };
// 新增
case REDUCE_COUNT:
return { count: state.count - action.num };
default:
return state;
}
}
import { addCount, reduceCount } from './store/actions/countAction';
/** 其余代码 **/
/** mapStateToProps **/
function mapActionToProps(dispatch) {
return {
addCount: () => dispatch(addCount()),
reduceCount: (num) => dispatch(reduceCount(num))
}
}
接着在组件中直接调用this.props.reduceCount()方法,并传入一个参数即可
最后,为了遵循react的规范,我们需要在给组件定义props的时候,规定props的类型
首先在App.js或者使用store的组件中,引入prop-types
然后在文件最末尾,抛出之前,定义所有的props的类型
import PropTypes from 'prop-types';
/** 其余代码 **/
App.propTypes = {
count: PropTypes.number.isRequired,
addCount: PropTypes.func.isRequired,
reduceCount: PropTypes.func.isRequired
}
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
import React, {Component} from 'react';
import { connect } from 'react-redux';
import { addCount, reduceCount } from './store/actions/countAction';
import PropTypes from 'prop-types';
class App extends Component {
render() {
return (
<div>
<button onClick={()=>this.props.addCount()}>加1</button>
{this.props.count}
<button onClick={()=>this.props.reduceCount(5)}>减5</button>
</div>
);
}
}
function mapStateToProps(state) {
return {
count: state.countReducer.count
}
}
function mapActionToProps(dispatch) {
return {
addCount: () => dispatch(addCount()),
reduceCount: (num) => dispatch(reduceCount(num))
}
}
App.propTypes = {
count: PropTypes.number.isRequired,
addCount: PropTypes.func.isRequired,
reduceCount: PropTypes.func.isRequired
}
export default connect(mapStateToProps,mapActionToProps)(App);
import { createStore, combineReducers } from 'redux';
import countReducer from './reducers/countReducer';
const rootReducer = combineReducers({
countReducer
})
const initializeState = {}; // 定义初始化的state
const store = createStore(rootReducer,initializeState);
export default store;
export const ADD_COUNT = 'ADD_COUNT';
export const REDUCE_COUNT = 'REDUCE_COUNT';
import { ADD_COUNT, REDUCE_COUNT } from '../actionTypes'
const initializeState = {
count: 1
}
export default function countReducer(state = initializeState,action) {
switch (action.type) {
case ADD_COUNT:
return { count: state.count + 1 };
case REDUCE_COUNT:
return { count: state.count - action.num };
default:
return state;
}
}
import { ADD_COUNT, REDUCE_COUNT } from '../actionTypes'
export function addCount() {
return {
type: ADD_COUNT
}
}
export function reduceCount(num) {
return {
type: REDUCE_COUNT,
num
}
}
import { createStore, combineReducers, applyMiddleware } from 'redux';
// 引入redux-thunk
import thunk from 'redux-thunk';
// 定义中间件的数组
const middleware = [ thunk ]
// 使用
const store = createStore(rootReducer,initializeState,applyMiddleware(...middleware));