redux学习

2020-01-02  本文已影响0人  回不去的那些时光

知识点

action

官方的解释是action是把数据从应用传到 store 的有效载荷,它是 store 数据的唯一来源;要通过本地或远程组件更改状态,需要分发一个action

action type

action的type

reducer

action发出了做某件事的请求,只是描述了要做某件事,并没有去改变state来更新界面,reducer就是根据action的type来处理不同的事件

store

store就是把action和reducer联系到一起的对象,store本质上是一个状态树,保存了所有对象的状态。任何UI组件都可以直接从store访问特定对象的状态

开启redux工具

redux如果要使用google浏览器的redux工具调试,需要在createStore中加入

window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

案例

创建Redux的仓库store和reducer并使用

默认已经使用 create-react-app 初始化好项目并且已经安装 redux 了

import { createStore } from 'redux' // 引入createStore

const store = createStore()  // 创建数据存储仓库

export default store                // 暴露出去
const defaultState = {                      // 默认数据
    inputValue: 'Write Something',
    list: [
        '早上6点起床,锻炼身体',
        '晚上跑步一小时'
    ]
}                             

export default (state = defaultState, action) => {  // 就是一个方法函数
    return state
}

index.js变成这样了

import { createStore } from 'redux' // 引入createStore
// ------------- 重点 ---------------
import reducer from './reducer'     // 引入reducer

const store = createStore(reducer)  // 创建数据存储仓库

export default store                // 暴露出去

在使用的文件中引入store,并在构造函数constructor中获取state

import store from './store'

constructor(props) {
    super(props)
    this.state = store.getState()
}

这样 redux 中的数据就和使用的地方产生关联了

加入Redux DevTools插件

在 reducer.js 中加入 window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

import { createStore } from 'redux' // 引入createStore
import reducer from './reducer'     // 引入reducer

// ----------------- 重点 ----------------
const store = createStore(reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())  // 创建数据存储仓库

export default store                // 暴露出去

加入这段代码后,就可以使用 redux 调试工具调试数据了

让redux工作起来

redux是管理数据的仓库,现在让他起作用吧!

<Input 
    onChange={this.changeInputValue} 
    placeholder={this.state.inputValue} 
    style={{ width: '250px', marginRight: '10px' }} />

changeInputValue = (e) => {
    const action = {
        type: 'changeInputValue',
        value: e.target.value
    }
    store.dispatch(action)
}
constructor(props) {
    super(props)
    this.state = store.getState()
    // 订阅redux状态
    store.subscribe(this.storeChange)  
}

storeChange = () => {
    this.setState(store.getState())
}
export default (state = defaultState, action) => {  // 就是一个方法函数
    if(action.type === 'changeInputValue') {
        let newState = JSON.parse(JSON.stringify(state))  // 深度拷贝state
        newState.inputValue = action.value
        return newState
    }

    return state
}
// TodoList.js
import React, { Component } from 'react'
import 'antd/dist/antd.css'
import { Input, Button, List } from 'antd'
import store from './store'

export default class TodoList extends Component {
    constructor(props) {
        super(props)
        this.state = store.getState()
        // 订阅redux状态
        store.subscribe(this.storeChange)  
    }

    storeChange = () => {
        this.setState(store.getState())
    }

    render() {
        return (
            <div style={{ margin: '10px' }}>
                <div>
                    <Input 
                        onChange={this.changeInputValue} 
                        placeholder={this.state.inputValue} 
                        style={{ width: '250px', marginRight: '10px' }} />
                    <Button type="primary">增加</Button>
                </div>

                <div style={{ margin: '10px', width: '300px' }}>
                    <List
                        bordered
                        dataSource={this.state.list}
                        renderItem={item => (
                            <List.Item>{item}</List.Item>
                        )}
                    >
                    </List>
                </div>
            </div>
        )
    }

    // input输入
    changeInputValue = (e) => {
        const action = {
            type: 'changeInputValue',
            value: e.target.value
        }
        store.dispatch(action)
    }
}
// reducer.js
const defaultState = {                      // 默认数据
    inputValue: 'Write Something',
    list: [
        '早上6点起床,锻炼身体',
        '晚上跑步一小时'
    ]
}                             

export default (state = defaultState, action) => {  // 就是一个方法函数
    if(action.type === 'changeInputValue') {
        let newState = JSON.parse(JSON.stringify(state))  // 深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    return state
}

把 Action Types 抽出来,单独写一个文件

export const CHANGE_INPUT_VALUE = 'changeInputValue'
export const ADD_ITEM = 'addItem'
export const DELETE_ITEM = 'deleteItem'
import { CHANGE_INPUT_VALUE, ADD_ITEM, DELETE_ITEM } from './store/actionTypes'

// input输入
changeInputValue = (e) => {
    const action = {
        type: CHANGE_INPUT_VALUE,
        value: e.target.value
    }
    store.dispatch(action)
}

// 点击按钮
clickBtn = () => {
    const action = { 
        type: ADD_ITEM
    }
    store.dispatch(action)
}

// 删除todo
deleteItem = (index) => {
    const action = {
        type: DELETE_ITEM,
        index
    }
    store.dispatch(action)
}
import { CHANGE_INPUT_VALUE, ADD_ITEM, DELETE_ITEM } from './actionTypes'
import { Modal } from 'antd';

const defaultState = {                      // 默认数据
    inputValue: '',
    list: [
        '早上6点起床,锻炼身体',
        '晚上跑步一小时'
    ]
}

export default (state = defaultState, action) => {  // 就是一个方法函数
    // console.log(state ,action)
    if (action.type === CHANGE_INPUT_VALUE) {        // input输入
        let newState = JSON.parse(JSON.stringify(state))  // 深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    if (action.type === ADD_ITEM) {             // 添加item
        let newState = JSON.parse(JSON.stringify(state))
        if (!newState.inputValue) {
            Modal.error({
                title: '提示信息',
                content: '输入框不能为空!'
            });
            return
        }
        newState.list.push(newState.inputValue)
        newState.inputValue = ''
        return newState
    }
    if (action.type === DELETE_ITEM) {              // 删除item
        let newState = JSON.parse(JSON.stringify(state))
        newState.list.splice(action.index, 1)
        return newState
    }

    return state
}

把 Redux Action 抽出来

import { CHANGE_INPUT_VALUE, ADD_ITEM, DELETE_ITEM } from './actionTypes'

export const changeInputAction = (value) => ({
    type: CHANGE_INPUT_VALUE,
    value
})

export const addItemAction = () => ({
    type: ADD_ITEM
})

export const deleteItemAction = (index) => ({
    type: DELETE_ITEM,
    index
})
import { changeInputAction, addItemAction, deleteItemAction } from './store/actionCreators'

// input输入
changeInputValue = (e) => {
    // const action = {
    //     type: CHANGE_INPUT_VALUE,
    //     value: e.target.value
    // }
    const action = changeInputAction(e.target.value)
    store.dispatch(action)
}

// 点击按钮
clickBtn = () => {
    // const action = { 
    //     type: ADD_ITEM
    // }
    const action = addItemAction()
    store.dispatch(action)
}

// 删除todo
deleteItem = (index) => {
    // const action = {
    //     type: DELETE_ITEM,
    //     index
    // }
    const action = deleteItemAction(index)
    store.dispatch(action)
}

redux的三个注意要点

上一篇 下一篇

猜你喜欢

热点阅读