Redux的学习笔记-(一)(B站学习笔记)

零,对应的视频学习资料

https://www.bilibili.com/video/BV1w441137ss
项目地址:https://gitee.com/ling-xu/react-redux-demo
对应此视频的系列笔记:
1-15节redux:https://blog.csdn.net/weixin_42349568/article/details/117196231
16-17节-redux-chunk:https://blog.csdn.net/weixin_42349568/article/details/117248649
18-19节-redux-saga:https://blog.csdn.net/weixin_42349568/article/details/117251408
20-24节-react-redux:https://blog.csdn.net/weixin_42349568/article/details/117266913

一,redux解决了什么问题

在这里插入图片描述

​ 在没有redux的时候,react的各个组件间的数据传递如左图所示,只能挨个进行,如果紫色组件需要修改其他组件的状态值,就需要一个个组件传递数据状态的变化。

​ 而引入redux之后,就相当于在全局区域创建了一个专门用来管理状态值的仓库,通过紫色组件修改这个仓库对应的值,就可以完成依赖于这个值的其他组件的状态更新。(单向数据流,子修改store,依赖于store的会自动更新修改)

二,redux的工作流程

在这里插入图片描述

在这里插入图片描述

在react的组件中,不再使用自身的状态,而是通过action从store中去查找使用里面存放的状态,而这些状态的管理体系,就是这个reducers.

三,实际小demo

1,安装antd

 npm install antd --save

2,新建todolist组件

import React from 'react'
import 'antd/dist/antd.css'
import { Input, Button, List } from 'antd'
const data = ['早上八点,需需求沟通', '早上九点,吃零食', '早上10点,摸鱼开始']
class TodoList extends React.Component {
	render() {
		return (
			<div>
				<div style={{ margin: '10px', display: 'flex', justifyContent: 'space-between' }}>
					<Input placeholder="添加待办事项" style={{ borderRadius: '5px' }} />
					<Button type="primary" style={{ width: '60px', height: '40px', marginLeft: '10px', borderRadius: '6px' }}>
						增加
					</Button>
				</div>
				<div style={{ margin: '10px' }}>
                    <List 
                        bordered 
                        dataSource={data} 
                        renderItem={item => <List.Item>{item}</List.Item>}>
                        </List>
				</div>
			</div>
		)
	}
}

export default TodoList

在这里插入图片描述

3,安装redux

npm install --save redux

4,创建一个仓库store

index.js:

import {createStore} from 'redux'
const store = createStore()
export default store

5,创建一个reducer,完成仓库中的数据内容管理

reducer.js

const defaultState = {
    inputValue:'请添加待办事项',
    list:['早上八点,需需求沟通', '早上九点,吃零食', '早上10点,摸鱼开始']
}
const reducer= (state = defaultState, action) => {
	return state
}
export default reducer

然后再修改index.js

import {createStore} from 'redux'
import reducer from './reducer'
const store = createStore(reducer)
export default store

然后再在页面组件上获取这个值完成渲染:

在这里插入图片描述

6,谷歌扩展程序安装Redux DevTools

然后在index.js修改:

import {createStore} from 'redux'
import reducer from './reducer'
const store = createStore(reducer,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
export default store

就可以使用啦:

在这里插入图片描述

7,修改store中地数据

使用的是store.dispatch方法,一旦调用这个函数,则会执行reducer方法,且形参action为传递进去的对象。

在这里插入图片描述

8,使用store.subscribe(this.storeChange)注册订阅

当我们通过store.dispatch方法修改更新了store中的数据内容,但是组件中并不会完成更新:

在这里插入图片描述

当我点击菜单,可以看到,store中的数据已经修改了,但是页面渲染的数据并没有发生变化,也就是并没有从store中获取到最新的数据。

在这里插入图片描述

这就需要注册监听数据变化:一旦store数据变化,就执行某个传入的回调函数,更新当前组件的state:

在这里插入图片描述

9,实现删除功能

在这里插入图片描述

10,把action的状态抽离出来形成action-type.js文件

在这里插入图片描述

这样就可以统一管理状态,降低了bug的出现概率。

11,把所有的action抽离出来形成独立的action文件

在这里插入图片描述

12,redux的一些坑

1,store必须是唯一的,只能有一个store空间。
2,只有store才能改变自己的内容(reducer返回新的state,传给createStore内部函数处理。),reducer不能改变(所以之前是深拷贝一份进行处理)
3,reducer必须是纯函数(同样的输入必须对应确定的唯一结果)

四,将ui和js实现分离

实际上是把ui部分抽离出来,形成一个独立的组件,然后其中的数据和方法,通过属性绑定的形式,props接收来实现。

ui组件:

import React from 'react'
import { Input, Button, List } from 'antd'
import 'antd/dist/antd.css'
class TodoListUI extends React.Component {
	render() {
		return (
			<div>
				<div style={{ margin: '10px', display: 'flex', justifyContent: 'space-between' }}>
					<Input
						placeholder={this.props.inputValue}
						style={{ borderRadius: '5px' }}
						onChange={this.props.inputChange}
						value={this.props.inputValue}
					/>
					<Button type="primary" onClick={this.props.addItem} style={{ width: '60px', height: '40px', marginLeft: '10px', borderRadius: '6px' }}>
						增加
					</Button>
				</div>
				<div style={{ margin: '10px' }}>
					<List
						bordered
						dataSource={this.props.list}
						renderItem={(item, index) => <List.Item onClick={()=>{this.props.deleteItem(index)}}>{item}</List.Item>}
					></List>
				</div>
			</div>
		)
	}
}

export default TodoListUI

导入使用ui组件:

import React from 'react'
import 'antd/dist/antd.css'

import store from './redux/index'
import {inputChangeActionn,deleteItemActionn,addItemActionn} from './redux/action'
import TodoListUI from './TodoListUI'
class TodoList extends React.Component {
    constructor(props){
        super(props)
        this.state=store.getState()
        this.storeChange=this.storeChange.bind(this)
        store.subscribe(this.storeChange)
        this.addItem=this.addItem.bind(this)
        this.deleteItem=this.deleteItem.bind(this)
    }
    storeChange(){
        this.setState(store.getState())
    }
    inputChange(e){
        // console.log(e.target.value)
        const action=inputChangeActionn(e.target.value)
        store.dispatch(action)
    }
    deleteItem(index){
        const action=deleteItemActionn(index)
        store.dispatch(action)
    }
    addItem(){
        const action=addItemActionn()
        if(this.state.inputValue ===''){
            console.log("kogn ")
            return
        }
        store.dispatch(action)
    }
	render() {
		return (
            <TodoListUI
                inputValue={this.state.inputValue}
                list={this.state.list}
                inputChange={this.inputChange}
                addItem={this.addItem}
                deleteItem={this.deleteItem}
            ></TodoListUI>
		)
	}
}
export default TodoList

五,组件更改为无状态的组件(函数式组件)

注意到现在的组件,是从store中获取状态值,所以说他可以变更为无状态组件的写法:

import React from 'react'
import { Input, Button, List } from 'antd'
import 'antd/dist/antd.css'
const TodoListUI=(props)=>{
    return (
        <div>
            <div style={{ margin: '10px', display: 'flex', justifyContent: 'space-between' }}>
                <Input
                    placeholder={props.inputValue}
                    style={{ borderRadius: '5px' }}
                    onChange={props.inputChange}
                    value={props.inputValue}
                />
                <Button type="primary" onClick={props.addItem} style={{ width: '60px', height: '40px', marginLeft: '10px', borderRadius: '6px' }}>
                    增加
                </Button>
            </div>
            <div style={{ margin: '10px' }}>
                <List
                    bordered
                    dataSource={props.list}
                    renderItem={(item, index) => <List.Item onClick={()=>{props.deleteItem(index)}}>{item}</List.Item>}
                ></List>
            </div>
        </div>
    )
}
export default TodoListUI

六,fastmock新建接口,从axios初始化数据

componentDidMount(){
        axios.get('https://www.fastmock.site/mock/88bbb3bb8d6ea3dc8f09431a61ce2e50/mymock_test/api/list')
        .then((res)=>{
            console.log(res)
            const action=getList(res)
            store.dispatch(action)
        })
    }

从axios初始化数据

componentDidMount(){
        axios.get('https://www.fastmock.site/mock/88bbb3bb8d6ea3dc8f09431a61ce2e50/mymock_test/api/list')
        .then((res)=>{
            console.log(res)
            const action=getList(res)
            store.dispatch(action)
        })
    }

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值