redux&react-redux(二)

简介: redux&react-redux(二)

4、一个简单的todolist案列(包含数据持久化)


4.0、redux&react-redux 项目结构

store
  index.js 创建一个store容器
  views
  Lists——>这个名是看文件,语义化就好了
    redux 
    - Actions.js   返回一个或多个动作对象,一般为`{type:'',data:''}`
    - ActionsTypes.js   返回一个或多个常量,用做Actions和Reducer的type值
    - Reducer.js    返回一个纯函数,用于处理动作对象
    index.js    将actions和reducer函数集中导出(方便管理)
    index.jsx    容器组件和UI组件的结合体


数据持久化看src/store/index.js 、 src/router.js


4.1 src/store/index.js

此文件主要就是创建一个仓库

将需要用到的reducer文件引入

从本地存储中取值,放进createStore的第二个参数,初始值的作用

import { createStore, combineReducers,applyMiddleware } from 'redux';
import thunk = 'react-thunk' //支持异步
import { reducer as lists } from '../views/Lists/_index.js'
const reducer = combineReducers({
  lists
})
let initList = JSON.parse(localStorage.getItem("LIST")) || [];
export default createStore(reducer,initList,applyMiddleware(thunk));


4.2 src/router.js

此文件主要就是做一个根组件

通过provider向下传递store

通过subscrbe方法订阅store

getState方法获取store的值存入本地

import React from 'react';
import App from './App';
import { Provider } from 'react-redux';
import Store from './store'
const StoreToken = Store.subscribe(() => {
  // Store.getState()
  // console.log(Store.getState())
  window.localStorage.setItem("LIST", JSON.stringify(Store.getState()))
})
//StoreToken() 这样可以取消订阅
const Router = () => {
  return (
    <div>
      <Provider store={Store}>
        <App />
      </Provider>
    </div>
  )
}
export default Router


4.3 src/List/redux/actions.js

此文件主要是返回一个action动作对象

action动作对象必须要有一个type属性

import * as actiontypes from './actionTypes';
export const addList = (data) => ({ type: actiontypes.ADDList, data })
export const delList = (data) => ({ type: actiontypes.DELLIST, data })


4.4 src/List/redux/actionTypes.js

此文件主要是返回一个常量,目的是防止出现字母错误(默认是大写)

export const ADDList = "ADDLIST";
export const DELLIST = "DELLIST";


4.5 src/List/redux/reducer.js

此文件返回一个纯函数,用于接收dispatch传来的action,进行处理之后返回store

默认注入两个参数(preState,action)

preState需要设置初始值

reducer被第一次调用时,是store自动触发的,传递的preState是undefined

必须要有默认返回值

import * as actionTypes from './actionTypes';
const reducer = (preState = [], action) => {
  const { type, data } = action;
  switch (type) {
    case actionTypes.ADDList:
      const result = [
        data,
        ...preState
      ]
      console.log(result)
      return result
    case actionTypes.DELLIST:
      preState.splice(data, 1)
      return [...preState]
    default:
      return preState
  }
}
export default reducer


4.6 src/List/_index.js

汇总action和reducer方便管理

actions文件只有一个

reducer文件或许会有多个

import * as actions from './redux/actions';
import reducer from './redux/reducer';
export { actions, reducer }


4.7-1 src/List/_index.js (类组件写法)

类组件中获取cannect中函数映射的值和函数都是通过props拿到的

import React,{Component} from 'react';
import { connect } from 'react-redux';
import * as actions from './redux/actions';
class View extends Component{
  // 渲染函数
  rLsits = () => {
    let { lists } = this.props;
    return lists.map((value, index) => (
      <li key={index}>{value} <button onClick={()=>{this.delfn(index)}}>删除</button></li>
    ))
  }
    // 添加数据
  send = () => {
    let val = this.inp.value;
    this.props.addLists(val)
    this.inp.value=""
  }
   // 删除数据
   delfn = (index) => {
     this.props.delLists(index)
  }
  render() {
    return (
      <div>
        <h2>这是一个class类组件操作数组数据的例子</h2>
        <input ref={value=>this.inp=value} type="text" />
        <button onClick={()=>{this.send()}}>发送</button>
        {this.rLsits()}
      </div>
    )
  }
}
// 写法一  mapDispatchToProps是一个对象
export default connect(
  state => ({ lists: state.lists }),
  {
    addLists: actions.addList,
    delLists: actions.delList
  }
)(View)
// 写法二   mapDispatchToProps是一个函数
// export default connect(
//   state => ({ lists: state.lists }),
//   (dispatch, ownProps) => ({
//     addLists: data => { dispatch(actions.addList(data)) },
//     delLists: data => { dispatch(actions.delList(data)) }
//   })
// )(View)
// 写法三   mapDispatchToProps为null
// 需要在UI组件内通过this.props.dispath传递action动作对象
// export default connect(
//   state => ({ lists: state.lists }),
//   null
// )(View)


4.7-2 src/List/_index.js (函数组件写法)

函数组件的值是通过useSelector拿到的

函数组件的dispatch是通过useDispatch 拿到的

import React,{useRef} from 'react';
import { useSelector, useDispatch } from 'react-redux';
import * as actions from './redux/actions'
const View = () => {
  let inp = useRef();
  const state = useSelector(state=>state)
  const dispath = useDispatch()
  const rLsits = () => {
    console.log('我执行了')
    return state.lists.map((value, index) => (
      <li key={index}>{value} <button onClick={()=>{delLists(index)}}>删除</button></li>
    ))
  }
  // 添加数据
  const send = () => {
    let val = inp.current.value;
    dispath(actions.addList(val))
    inp.current.value=""
  }
  // 删除数据
  const delLists = (index) => {
     dispath(actions.delList(index))
  }
  return (
    <div>
      <h2>这是一个函数组件操作数组数据的例子</h2>
      <input ref={inp} type="text" />
      <button onClick={send}>发送</button>
      {rLsits()}
    </div>
  )
}
export default View;


【补】纯函数


一类特别的函数:只要是同样的输入(实参),必定得到同样的输出(返回)

必须遵守以下一些约束

不得改写数据

不会产生任何副作用,例如网络请求,输入和输出设备

不能调用Date.now()或者Math.random()等不纯的方法

相关文章
|
4月前
|
前端开发 JavaScript 测试技术
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
133 0
|
30天前
|
存储 JavaScript 前端开发
React中使用redux
React中使用redux
127 56
|
22天前
|
存储 JavaScript 前端开发
react redux 实现原理
【8月更文挑战第29天】react redux 实现原理
17 4
|
19天前
|
前端开发 Java UED
瞬间变身高手!JSF 与 Ajax 强强联手,打造极致用户体验的富客户端应用,让你的应用焕然一新!
【8月更文挑战第31天】JavaServer Faces (JSF) 是 Java EE 标准的一部分,常用于构建企业级 Web 应用。传统 JSF 应用采用全页面刷新方式,可能影响用户体验。通过集成 Ajax 技术,可以显著提升应用的响应速度和交互性。本文详细介绍如何在 JSF 应用中使用 Ajax 构建富客户端应用,并通过具体示例展示 Ajax 在 JSF 中的应用。首先,确保安装 JDK 和支持 Java EE 的应用服务器(如 Apache Tomcat 或 WildFly)。
27 0
|
20天前
|
存储 JavaScript 前端开发
探索React状态管理:Redux的严格与功能、MobX的简洁与直观、Context API的原生与易用——详细对比及应用案例分析
【8月更文挑战第31天】在React开发中,状态管理对于构建大型应用至关重要。本文将探讨三种主流状态管理方案:Redux、MobX和Context API。Redux采用单一存储模型,提供预测性状态更新;MobX利用装饰器语法,使状态修改更直观;Context API则允许跨组件状态共享,无需第三方库。每种方案各具特色,适用于不同场景,选择合适的工具能让React应用更加高效有序。
31 0
|
30天前
|
存储 JavaScript 前端开发
"探索Redux的Vuex化:如何在React世界中享受Vue状态管理的优雅与强大"
【8月更文挑战第21天】在现代前端开发中,状态管理至关重要。Vuex作为Vue.js的状态管理库,通过集中式存储和严格规则确保状态变更的追踪。Redux则以其在React生态中的可预测性和灵活性著称。两者都强调单一数据源、状态只读及使用纯函数变更状态。尽管API设计不同,理解Redux的核心概念——单一数据源(`store`)、状态只读与纯函数变更(`reducers`),并参考Vuex的`state`、`mutations`等,能帮助开发者快速掌握Redux,高效管理应用状态。
15 0
|
1月前
|
JavaScript 前端开发 安全
|
2月前
|
Web App开发 JavaScript 前端开发
react18【系列实用教程】搭建开发环境(2024版)Vite+React (官方推荐)(含@配置,react-developer-tools 和 Redux DevTools 下载安装)
react18【系列实用教程】搭建开发环境(2024版)Vite+React (官方推荐)(含@配置,react-developer-tools 和 Redux DevTools 下载安装)
182 0
|
4月前
|
存储 JavaScript 前端开发
基于React和Redux的待办事项列表应用
基于React和Redux的待办事项列表应用
52 0
|
4月前
|
JavaScript 前端开发 搜索推荐
构建一个基于React和Redux的简易电商购物车应用
构建一个基于React和Redux的简易电商购物车应用
53 0

热门文章

最新文章