文章目录
1 引入
- 解决组件之间传值问题(类似于vue中的vuex)
2 使用
2.1 基本使用
- 下载依赖
- 创建store文件夹/index.js
- 编写reducer.js
- 暴露
- 引入和使用
2.1.1 下载依赖
cnpm i redux -S
2.1.2 使用
- store/reducer/index.js
- 要存储的数据
- 可以设置默认值,暴露为一个函数
const defaultProps = {
count:0
}
export default (state=defaultProps,action)=>{
return state
}
2.1.3 暴露存储的数据
- store/index.js
- 使用的依赖为redux中一个
createStore
对象
import {createStore} from 'redux'
import Reducer from './reducer'
export default createStore(Reducer)
2.1.4 使用存储数据
- APP.js中使用
- 获取值为
store.getState()
import React,{Component} from 'react'
import store from './store'
export default class APP extends Component{
constructor() {
super();
this.state=store.getState()
}
render() {
return(
<div>
{this.state.count}
</div>
)
}
}
2.2 常见使用(react-redux)
2.2.1 引入
- 使用依赖
react
redux
react-redux
- 实现修改数据
- 使用
element-ui
2.2.2 创建项目
-
项目结构
-
首次进入
2.2.3 开发
- 引入
element-ui
- 页面结构
- 编写点击事件
1 引入ele
- 下载依赖
cnpm i react redux react-redux react-hot-loader -S
- 在入口文件
index.js
中引入import 'element-theme-default'
2 页面结构
- APP.js
import React,{Component} from 'react'
import store from './store'
import {Button} from 'element-react'
export default class APP extends Component{
constructor() {
super();
this.state = store.getState()
}
render() {
return (
<div>
<Button type='primary'>-</Button>
<span style={{margin:'0 10px',
fontSize:20}}>{this.state.count}</span>
<Button type='primary'>+</Button>
</div>
)
}
}
3 文件
- index.js 配置
react-redux
Producer
一定带属性store
import React from 'react';
import ReactDOM from 'react-dom';
import APP from "./APP";
import 'element-theme-default'
import store from './store'
import {Provider} from 'react-redux'
ReactDOM.render(
<Provider store={store}>
<APP/>
</Provider>
,
document.getElementById('root')
);
- APP.js
import React,{Component} from 'react'
import {Button} from 'element-react'
import {connect} from 'react-redux'
class APP extends Component{
constructor() {
super();
}
render() {
return (
<div>
<Button type='primary' onClick={this.props.subCount}>-</Button>
<span style={{margin:'0 10px',
fontSize:20}}>{this.props.count}</span>
<Button type='primary' onClick={this.props.addCount}>+</Button>
</div>
)
}
}
const mapProps = state =>{
return{
count:state.count
}
}
const mapActions = dispatch =>{
return{
addCount(){
dispatch({
type:`ADD_COUNT`,
value:1
})
},
subCount(){
dispatch({
type:`SUB_COUNT`,
value:1
})
}
}
}
export default connect(mapProps,mapActions)(APP)
- redux/index.js
const defaultProp = {
count:0
}
export default (state=defaultProp,action)=>{
switch (action.type) {
case "ADD_COUNT":
const newState = JSON.parse(JSON.stringify(state))
newState.count += action.value
return newState
case "SUB_COUNT":
const subState = JSON.parse(JSON.stringify(state))
subState.count -= action.value
return subState
default:
return state
}
}
- store.js
import {createStore} from 'redux'
import reducer from './reducer'
export default createStore(reducer)
2.3 组件化
- 将
actions
抽离 - 常量抽离
- action/index.js
import {ADD_COUNT,SUB_COUNT } from '../types'
export const addCount = value=> {
return{
type:ADD_COUNT,
value
}
}
export const subCount = value => {
return{
type:SUB_COUNT,
value
}
}
- reducer/index.js
import {ADD_COUNT,SUB_COUNT} from '../types'
const defaultProp = {
count:0
}
export default (state=defaultProp,action)=>{
switch (action.type) {
case ADD_COUNT:
const newState = JSON.parse(JSON.stringify(state))
newState.count += action.value
return newState
case SUB_COUNT:
const subState = JSON.parse(JSON.stringify(state))
subState.count -= action.value
return subState
default:
return state
}
}
- types/index.js
export const ADD_COUNT = 'ADD_COUNT'
export const SUB_COUNT = 'SUB_COUNT'
- APP.js
import React,{Component} from 'react'
import {Button} from 'element-react'
import {connect} from 'react-redux'
import {addCount,subCount} from './store/actions'
class APP extends Component{
constructor() {
super();
}
render() {
return (
<div>
<Button type='primary' onClick={this.props.subCount}>-</Button>
<span style={{margin:'0 10px',
fontSize:20}}>{this.props.count}</span>
<Button type='primary' onClick={this.props.addCount}>+</Button>
</div>
)
}
}
const mapProps = state =>{
return{
count:state.count
}
}
const mapActions = dispatch =>{
return{
addCount(){
dispatch(addCount(4))
},
subCount(){
dispatch(subCount(2))
}
}
}
export default connect(mapProps,mapActions)(APP)
2.4 axios (react-thunk)
- axios 请求需要使用依赖
react-thunk
2.4.1 下载依赖
cnpm i react-thunk axios -S
2.4.2 配置入口文件
- store/index.js
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk';
const composeEnhancers =
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
applyMiddleware(thunk),
);
const store = createStore(
reducer,//构建初始的数据
enhancer
)
export default store
2.4.3 编写请求方法
- actions/index.js
export const getList = value => {
return{
type:GET_LIST,
value
}
}
export const getTodos = number => dispatch => {
axios
.get('http://jsonplaceholder.typicode.com/todos')
.then(todos => {
// 把actions 发送给 reducer
console.log(todos)
dispatch(getList(todos))
})
}
- reducer.js
import {ADD_COUNT,SUB_COUNT,GET_LIST} from '../types'
const defaultProp = {
count:0,
todos:[]
}
export default (state=defaultProp,action)=>{
switch (action.type) {
case ADD_COUNT:
const newState = JSON.parse(JSON.stringify(state))
newState.count += action.value
return newState
case SUB_COUNT:
const subState = JSON.parse(JSON.stringify(state))
subState.count -= action.value
return subState
case GET_LIST:
const newList = JSON.parse(JSON.stringify(state))
newList.todos = action.value.data
return newList
default:
return state
}
}
- types/index.js
export const ADD_COUNT = 'ADD_COUNT'
export const SUB_COUNT = 'SUB_COUNT'
export const GET_LIST = 'GET_LIST'
- APP.js
import React,{Component} from 'react'
import {Button} from 'element-react'
import {connect} from 'react-redux'
import {addCount,subCount,getTodos} from './store/actions'
class APP extends Component{
constructor() {
super();
}
render() {
return (
<div>
app
<Button type='primary' onClick={this.props.subCount}>-</Button>
<span style={{margin:'0 10px',
fontSize:20}}>{this.props.count}</span>
<Button type='primary' onClick={this.props.addCount}>+</Button>
</div>
)
}
componentDidMount() {
this.props.getTodo()
}
}
const mapProps = state =>{
return{
count:state.count
}
}
const mapActions = dispatch =>{
return{
addCount(){
dispatch(addCount(4))
},
subCount(){
dispatch(subCount(2))
},
getTodo(){
dispatch(getTodos())
}
}
}
export default connect(mapProps,mapActions)(APP)
2.5 错误
TypeError: Cannot read property ‘getState’ of undefined
1 Provider 没有定义store属性
3 总结
3.1 react-redux使用
- 1 下载依赖
cnpm i react redux react-redux -S
- 2 在入口文件
index.js
中引入import {Provider} from 'react-redux'
<Provider store={store}> <APP/> </Provider>
store属性必须
- 3 在APP中使用
connect
是一个回调函数- 第一个参数: state
- 第二个参数:actions
- 在APP中的所有数据都来源于
props
事件也是如此 - actions中需要使用
dispatch({type:"ADD_COUNT",value:1})
4 源码
码云地址:https://gitee.com/lakerzhang/reducer.git