首页 > 其他分享 >react Redux 用Redux中央仓库实现一个todolist

react Redux 用Redux中央仓库实现一个todolist

时间:2023-01-03 15:36:24浏览次数:48  
标签:const todolist value react state action Redux type store


react Redux 用Redux中央仓库实现一个todolist_数据

 Redux简单介绍

Redux是一个用来管理管理数据状态和UI状态的JavaScript应用工具。随着JavaScript单页应用(SPA)开发日趋复杂,JavaScript需要管理比任何时候都要多的state(状态),Redux就是降低管理难度的。(Redux支持React,Angular、jQuery甚至纯JavaScript)

Redux Dev Tools插件 Redux调试工具 谷歌商店下载

 

redux三个坑:

store仓库必须是唯一的,多个store是坚决不允许,只能有一个store空间

只有store能改变自己的内容,Reducer不能改变

Reducer必须是纯函数

 

Redux-thunk这个Redux最常用的插件:

在Dispatch一个Action之后,到达reducer之前,进行一些额外的操作,就需要用到middleware(中间件)

在实际工作中你可以使用中间件来进行日志记录、创建崩溃报告,调用异步接口或者路由

npm install --save redux-thunk

 第一步 仓库 在store文件夹下新建index.js

//applyMiddleware,compose是为了使用下面两个插件
import {createStore,applyMiddleware,compose} from 'redux' //引入redux
import thunk from 'redux-thunk' //引入redux中间件插件
import reducer from './reducer' //引用reducer中的数据

//浏览器安装的仓库插件 调试面板
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose

//redux中间件插件 此函数为了兼容两个插件并行
const enhancer = composeEnhancers(applyMiddleware(thunk))

//定义一个仓库 唯一的 不能有两个仓库 createStore仓库只接收两个参数
const store = createStore( reducer, enhancer) // 创建数据存储仓库
export default store //将仓库导出

 新建reducer.js 做仓库数据处理

import {ADD_ITEM , DELETE_ITEM , GET_LIST} from './actionTypes' //定义type类型的js文件

const defaultState = {
value:'sss',
list:[] //后端获取的列表数据放在这里
}

// state: 指的是原始仓库里的状态。
// action: 指的是action新传递的状态。
export default (state = defaultState,action)=>{
// console.log(state)
//Reducer里只能接收state 不能改变state
// if(action.type ==="changeInput"){
// let newState = JSON.parse(JSON.stringify(state)) //深拷贝state的值 转成字符串 赋值给一个变量
// newState.value = action.vlaue //改变placeholder的值等于用户输入的值
// return newState //将新state return出去
// }
//增加
if(action.type === ADD_ITEM ){ //根据type值,编写业务逻辑
let newState = JSON.parse(JSON.stringify(state))
newState.list.push(action.value) //用户输入的新内容push新的内容到列表中去
console.log(action)
newState.value = '' //增加后清空
return newState
}

//删除
if(action.type === DELETE_ITEM ){
let newState = JSON.parse(JSON.stringify(state))
newState.list.splice(action.index,1) //删除数组中对应的值
return newState
}

//后端获取数据 传递给中央仓库做处理
if(action.type === GET_LIST ){
let newState = JSON.parse(JSON.stringify(state))
newState.list =action.data
return newState
}
return state
}

actionTypes.js   集中管理页面reducer的type类型

//集中管理页面reducer的type类型

export const ADD_ITEM = "addItem" //定义常量一般用大写
export const DELETE_ITEM = "deleteItem"
export const GET_LIST = "getListAction"

actionCreators.js  封装组件的action

//封装组件的action
import {ADD_ITEM , DELETE_ITEM ,GET_LIST} from './actionTypes' //定义type类型的js
import axios from 'axios'

//组件addItem里的action type已经封好 所以把value作为参数用箭头函数(value)=>传进来即可

//增加数据
export const addItem = (value)=>({
type:ADD_ITEM,
value
})

//删除数据
export const deleteItem = (index)=>({
type:DELETE_ITEM,
index
})

//获取数据
export const getListAction = (data)=>({
type:GET_LIST,
data
})

export const getTodoList = () =>{
return (dispatch)=>{
axios.get('https://www.easy-mock.com/mock/5d63d7ca5774121e1a634378/demo1/demo1')
.then((res)=>
{
const data = res.data.data;
const action = getListAction(data)
dispatch(action) //将action这个值传给仓库
})
.catch((error)=>{
console.log(error)
})
}
}

TodoList.js  组件js部分

import React, { Component } from 'react';
import TodoListUi from './TodoListUi' //组件UI部分
import store from '../store/index' //组件中获得store中的数据
//import {ADD_ITEM , DELETE_ITEM} from '../store/actionTypes' //定义type类型的js 为了更方便检查错误 写错会报错
import { addItem,deleteItem,getTodoList } from '../store/actionCreators' //封装的action


//用reducer写todolist 调用中央仓库

class TodoList extends Component {
constructor(props){
super(props)
// console.log(store.getState()) //getState方法取出仓库的值
this.state = store.getState() //将组件state数据赋值给仓库数据
this.changeInputVlaue = this.changeInputVlaue.bind(this) //给方法做this绑定
this.storeChange = this.storeChange.bind(this)
this.clickBtn = this.clickBtn.bind(this)
this.deleteItem = this.deleteItem.bind(this)
store.subscribe(this.storeChange) //订阅模式 改变数据时同步让仓库中的数据改变
}
render() {
return (
<TodoListUi
value={this.state.value}
changeInputVlaue={this.changeInputVlaue}
clickBtn={this.clickBtn}
list={this.state.list}
deleteItem = {this.deleteItem}
></TodoListUi>
);
}

componentDidMount(){
// axios.get('https://www.easy-mock.com/mock/5d63d7ca5774121e1a634378/demo1/demo1')
// .then((res)=>
// {
// const data = res.data.data;
// const action =getListAction(data) //将取到的数据封入action
// store.dispatch(action) //传递给reducer
// })
// .catch((error)=>{
// console.log(error)
// })
const action = getTodoList() //使用中间件获取数据
store.dispatch(action) //传给仓库
}
//用户输入的值传给仓库 要通过dispatch()方法传递给store
//Action就是一个对象,这个对象一般有两个属性,第一个是对Action的描述,第二个是要改变的值。
//之前注销的方法,在reducer里深拷贝完state里面的数据,无法同步将用户输入赋值给state
changeInputVlaue(e){
this.setState({
value:e.target.value //将用户输入的value绑定给仓库中的value,监听用户输入
})
// const action = {
// type:'changeInput', // 名字
// value:e.target.value //值
// }
// store.dispatch(action)
}

//state和组件的值同步互相改变
storeChange(){
this.setState(store.getState())
}

//增加 因为list数据存在中央仓库里 所以要做的是 将组件数据传给仓库 改变仓库数据后 再返回给组件展示
clickBtn(){
// console.log(this.state.value)
// const action = {
// type:ADD_ITEM,
// value:this.state.value //获取到用户value,用于push
// }
const action = addItem(this.state.value);
store.dispatch(action)
}
//删除
deleteItem(index){
// console.log(index)
// const action = {
// type:DELETE_ITEM,
// index //index传过去用于删除
// }
const action =deleteItem(index)
store.dispatch(action)
}
}
export default TodoList;

TodoListUi.js 组件UI部分抽离成子组件

//此文件用于视图和逻辑的分离
import React from 'react';
import 'antd/dist/antd.css' //引入Ant Design UI库
import { Input ,Button,List} from 'antd' //引入input组件

//无状态组件 提高性能 将组件改造成函数
const TodoListUi = (props)=>{
return (
<div style={{margin:"100px"}}>
<div>
<Input
style={{ width:"250px",marginRight:"20px"}}
onChange={props.changeInputVlaue}
value={props.value}
/>
<Button type='primary' onClick={props.clickBtn}>增加</Button>
</div>
<div style={{margin:"10px",width:"300px"}}>
<List
bordered //加边框
dataSource={props.list} //渲染什么数据
renderItem={(item,index)=>(<List.Item onClick={()=>{props.deleteItem(index)}}>{item}</List.Item>)} //每项
/>
</div>
</div>
);
}

//改造前组件 上边需要从react引入Component
// class TodoListUi extends Component {
// state = { }
// render() {
// return (
// <div style={{margin:"100px"}}>
// <div>
// <Input
// style={{ width:"250px",marginRight:"20px"}}
// onChange={this.props.changeInputVlaue}
// value={this.props.value}
// />
// <Button type='primary' onClick={this.props.clickBtn}>增加</Button>
// </div>
// <div style={{margin:"10px",width:"300px"}}>
// <List
// bordered //加边框
// dataSource={this.props.list} //渲染什么数据
// renderItem={(item,index)=>(<List.Item onClick={()=>{this.props.deleteItem(index)}}>{item}</List.Item>)} //每项
// />
// </div>
// </div>
// );
// }
// }

export default TodoListUi;

 

标签:const,todolist,value,react,state,action,Redux,type,store
From: https://blog.51cto.com/u_12422954/5986019

相关文章

  • React 小案例 无线首页底部导航组件
    效果:底部页面导航点击当前图标图标高亮页面结构1.将所用到的小图标文件放置在static文件夹下2.在src下新建tabbar文件夹,用于存放组件资源3.页面代码注意:将本页面的css引入......
  • React 小案例 路由跳转
    在上篇的基础上做路由跳转:​​上篇​​安装路由及代码:安装:cnpmi-Sreact-router-dom1.在pages里创建四个跳转页面 2.在src文件夹下创建router.js,router.js全部内容:首先引......
  • React 中用jQuery的ajax 和 axios请求数据
    目录结构 单页文件Records.js模拟一个mock数据:1.https://www.mockapi.io/ 可以使用github账号登陆2.新建项目3.我在此命名项目为accunt-app4.填写你数据的名字5.数据的......
  • react 基础 脚手架组件挂载 / 生命周期
    脚手架里的index.js配置组件的挂载importReactfrom'react'importReactDOMfrom'react-dom'//importLifefrom'./Life'importXiaojiejiefrom'./react/Xiaojiejie'......
  • React 小案例 用户评论
    功能展示:1.用户可输入用户名2.输入评论内容3.点击发布4.用户名和用户评论会被显示在列表里,第一个评论在最上面5.且显示本条评论离现在过去了多长时间6.鼠标放在事件上方可......
  • React 用axios 获取遍历json 引入swiper轮播图
    结构展示:功能展示:1.使用swiper轮播插件,2.自动轮播,当前图片高亮小按钮首先引入swiper和配置环境1.npminstall--saveswiper2.在src文件夹index.js下引入样式,避免打包失败im......
  • 记录报错 react Expected an assignment or function call and instead saw an expres
    报错:Expectedanassignmentorfunctioncallandinsteadsawanexpression no-unused-expressionsSearchforthekeywordstolearnmoreabouteacherror.期望一......
  • react Router 学习
     功能:1.进入项目后的默认路径是home,默认展示首页模块2.点击路由,切换子组件3.点击文章路由,根据传值不同进入三级详情路由,同时二级路由不显示4.点击返回首页,跳转到首页 安装......
  • react todolist 3
    功能:1.输入框输入事项,点击add,list增加一条,输入框清空并且聚焦;2.点击当前checkbox,勾选文字为已完成,取消勾选文字为未完成;父组件TodoList.js分成了三个子组件TodoHeader,TodoI......
  • react 做一个点赞按钮组件
      创建组件Like.js一开始设置为黑色false,isLiked如果为true渲染红心,false渲染黑心setState时用了两种方法importReact,{Component}from'react'exportdefaultclass......