超级详细react笔记(十二)redux篇

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值