react-redux的todolist(b站笔记)-(四)

前言,对应的视频教程是B站技术胖的redux视频教程,本文内容是对应20-24节。
视频地址:https://www.bilibili.com/video/BV1w441137ss?p=21
项目代码地址:https://gitee.com/ling-xu/react-rudex-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

一,新建项目

1,创建新项目

 npx create-react-app react-redux-demo

2,删除src下并不必要的文件(只保留index.js)

并修改index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
    <App />,
  document.getElementById('root')
);

3,安装react-redux

npm i react-redux

4,基本的todolist组件

import React, { Component } from 'react';
class TodoList extends Component {
    constructor(props) {
        super(props);
        this.state = {  }
    }
    render() { 
        return (
            <div>
                <div>
                    <input></input>
                    <button>提交</button>
                </div>
                <ul>
                    <li>测试</li>
                </ul>
            </div>
        );
    }
}
 
export default TodoList;

5,安装redux

npm i redux

二,照常使用redux

在这里插入图片描述
但是,这样一来,只有todolist这个组件使用到了这个仓库,如果有很多组件,都需要这个仓库的话,难道每个组件都要引用一次嘛?那也太麻烦了,为了让多个组件都可以直接访问store仓库,引入了react-redux,其中Provider组件就是解决这个问题的。

三,Provider和connect的使用

1,使用provider组件包裹的组件,都可以访问store仓库:

import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList'
import {Provider} from 'react-redux'
import store from './store/index'
const App=(
  <Provider store={store}>
    <TodoList />
  </Provider>
)
ReactDOM.render(
    App,
  document.getElementById('root')
);

2,使用connect和自定义映射函数获取store中的指定数据到组件参数中

import React, { Component } from 'react';
import {connect} from 'react-redux'
class TodoList extends Component {
    render() { 
        return (
            <div>
                <div>
                    <input placeholder={this.props.inputValue}></input>
                    <button>提交</button>
                </div>
                <ul>
                    <li>测试</li>
                </ul>
            </div>
        );
    }
}
//自定义映射函数,传入的参数state是store中的state,返回的就是这个组件接收到的props对象
const stateToProps=(state)=>{
    return {
        inputValue:state.inputValue
        //因为目前本组件只是用到inputValue这个值,所以只从store中取这个值,正常情况下可以取很多值
    }
}
//连接函数,第一个参数就是自定义的映射函数,把store中的state映射到组件TodoList的参数props上
export default connect(stateToProps,null)(TodoList);

这样一来,就可以在本组件中使用到store中的inputValue参数了。

3,使用diapatch更新store中的数据

import React, { Component } from 'react';
import {connect} from 'react-redux'
class TodoList extends Component {
    // inputChange(e){
    //     console.log(e.target.value)
    // }
    render() { 
        return (
            <div>
                <div>
                    <input 
                        value={this.props.inputValue}
                        placeholder="亲输入"
                        onChange={this.props.inputChange}
                        ></input>
                    <button>提交</button>
                </div>
                <ul>
                    <li>测试</li>
                </ul>
            </div>
        );
    }
}
//自定义映射函数,传入的参数state是store中的state,返回的就是这个组件接收到的props对象
const stateToProps=(state)=>{
    return {
        inputValue:state.inputValue
        //因为目前本组件只是用到inputValue这个值,所以只从store中取这个值,正常情况下可以取很多值
    }
}
const dispatchToProps=(dispatch)=>{
    return {
        inputChange(e){
            const action={
                type:'CHANGE_INPUT',
                value:e.target.value
            }
            dispatch(action)
        }
    }
}
//连接函数,第一个参数就是自定义的映射函数,把store中的state映射到组件TodoList的参数props上
export default connect(stateToProps,dispatchToProps)(TodoList);

要修改store中的inputValue值,必然要发起diapatch(action),这里主要是这行代码:

const dispatchToProps=(dispatch)=>{
    return {
        inputChange(e){
            const action={
                type:'CHANGE_INPUT',
                value:e.target.value
            }
            dispatch(action)
        }
    }
}

把inputChange映射为本组件的props中的一个方法,即传入的参数是dispatch函数,返回的对象中是绑定到本组件props中的方法(应该可以同时返回多个方法)。
然后利用连接函数的第二个参数上:

export default connect(stateToProps,dispatchToProps)(TodoList);

使用的时候:

<input 
  value={this.props.inputValue}
  placeholder="亲输入"
  onChange={this.props.inputChange}
  ></input>

4,对应的reducer处理:

const defaultState={
    inputValue:'',
    list:[]
}
const reducer=(state=defaultState,action)=>{
    if(action.type==='CHANGE_INPUT'){
        const newState=JSON.parse(JSON.stringify(state))
        newState.inputValue=action.value
        return newState
    }
    return state
}
export default reducer

5,完成新增事项的功能

todolist:

在这里插入图片描述
对应的reducer:

const defaultState={
    inputValue:'',
    list:[]
}
const reducer=(state=defaultState,action)=>{
    if(action.type==='CHANGE_INPUT'){
        const newState=JSON.parse(JSON.stringify(state))
        newState.inputValue=action.value
        return newState
    }
    if(action.type==='ADD_ITEM'){
        const newState=JSON.parse(JSON.stringify(state))
        newState.list.push(newState.inputValue)
        newState.inputValue=''
        return newState
    }
    return state
}
export default reducer

6,解构赋值简化代码

由上面的知识可以知道,connect函数把属性和方法全部映射到this.props这个对象中了,并且所有的属性和方法都在这个对象的第一层级上,于是就可以使用解构赋值的方式提取这些属性和方法,就不需要各种this.porps到处写了:
在这里插入图片描述
具体代码:

import React, { Component } from 'react';
import {connect} from 'react-redux'
class TodoList extends Component {
    render() { 
        let {inputValue,list,clickBtn,inputChange}=this.props
        return (
            <div>
                <div>
                    <input 
                        value={inputValue}
                        placeholder="请输入"
                        onChange={inputChange}
                        ></input>
                    <button onClick={clickBtn}>提交</button>
                </div>
                <ul>
                    {
                        list.map((item,index)=>{
                            return (
                                <li key={index}>{item}</li>
                            )
                        })
                    }
                </ul>
            </div>
        );
    }
}
//自定义映射函数,传入的参数state是store中的state,返回的就是这个组件接收到的props对象
const stateToProps=(state)=>{
    return {
        inputValue:state.inputValue,
        list:state.list
        //因为目前本组件只是用到inputValue这个值,所以只从store中取这个值,正常情况下可以取很多值
    }
}
const dispatchToProps=(dispatch)=>{
    return {
        inputChange(e){
            const action={
                type:'CHANGE_INPUT',
                value:e.target.value
            }
            dispatch(action)
        },
        clickBtn(){
            const action={
                type:'ADD_ITEM'
            }
            dispatch(action)
        }
    }
}
//连接函数,第一个参数就是自定义的映射函数,把store中的state映射到组件TodoList的参数props上
export default connect(stateToProps,dispatchToProps)(TodoList);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值