Redux

本文围绕Redux展开,介绍其概念、主要功能和工作流程,阐述了Redux的使用步骤及store的API。还讲解了React-redux的安装与具体使用,包括装饰器优化、异步处理和调试工具。此外,探讨了Redux进阶内容,如项目结构组织、state设计原则等。

1.1 概念

1.1.1 Redux 是什么

  • Redux 专注于状态管理,和React解耦(没有逻辑上的联系和依赖,可以分开使用)
  • 单一状态,单项数据流
  • 核心概念:store, state, action, reducer

1.1.2 主要功能

  • 有一个保险箱(store),所有人的状态在那里都有记录(state
  • 需要改变的时候,需要告诉 dispatch 要干什么(action
  • 处理变化的 reducer 拿到 stateaction,生成新的 state

1.1.3 工作流程

  • 首先通过 reducer 新建 store,随时通过 store.getState 获取状态
  • 需要状态变更,store.dispatch (action) 来修改状态
  • Reducer 函数接受 state 和 action,返回新的 state,可以用 store.subscribe 监听每次修改

![1553935619355](F:\我的学习\My Study\07-React\assets\1553935619355.png)

1.1.4 Redux的使用

1.创建 store
/* store.js */
import { createStore } from 'redux';
const store = createStore()
2. 创建 Action
/* action.js */

const LOGIN = "LOGIN"

export function loginAction (loginData) {
  return { 
    type: LOGIN,
    loginData // {status: false, user: 'xiaodingyang', password: '123456'}
  } 
}
3. 创建 reducer
/* reducer.js */

// state中的默认的数据
let initData = {
  msg: []
}
export function login (state = initData, action) {
  switch (action.type) {
    case LOGIN:
      return { ...state, msg: action.loginData }
    default:
      return {...state}
  }
}
4. 将 reducer 给 store
import reducer form './reducer';
import { createStore } from 'redux';
const store = createStore(reducer);
5. 将store和组件关联
ReactDOM.render(
  <Provider store={store}><App /></Provider>
  , document.getElementById('root'));
  • 然后就是使用了,使用会在下面具体展示

1.1.5 store的API

1. store.getState()
  • 获取state的状态

    console.log(store.getState()) 
    
2. store.subscribe()
  • 订阅 state 变化

    const unsubscribe = store.subscribe(()=>{
      console.log(state.getState())
    })
    unsubscribe() // 执行返回值可取消订阅
    
3. store.dispatch()
  • 提交 action

    store.dispatch(loginAction())
    
4. 最终 store.js
  • 我们在main.js中导入store.js,就会执行以下代码

    import { createStore } from 'redux';
    import { loginAction } from 'action.js';
    
    const store = createStore()
    console.log(store.getState()) 
    const unsubscribe = store.subscribe(()=>{
      console.log(state.getState())
    })
    unsubscribe() // 执行返回值可取消订阅
    store.dispatch(loginAction())
    

1.2 React-redux

1.2.1 安装

npm i react-redux --save
  • 安装完 react-redux 以后,就可以:
    • 忘记 subscribe,记住 reduceractiondispatch
    • React-redux 提供 Providerconnect 两个接口来连接

1.2.2 具体使用

  • Provider向根组件注入 Store,Provider 组件在应用最外层,传入 store 即可,只使用一次

  • connect连接 React 组件和 Redux 状态层,Connect 负责从外部获取组件需要的参数, Connect 可以用装饰器的方式来写

    /* index.js */
    
    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    
    // 引入redux
    import { createStore, applyMiddleware } from 'redux';
    import { counter } from './index-redux';
    import { Provider } from 'react-redux';
    
    const store = createStore(counter)  //新建 store
    
    ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('root')
    );
    
    /* index-redux */
    
    // 根据老的状态和action生成新的状态
    export function counter (state = 0, action) {
      switch (action.type) {
        case '加':
          return state + 1;
        case '减':
          return state - 1;
        default:
          return state
      }
    }
    
    export function add () {
      return { type: '加' }
    }
    export function reduce () {
      return { type: '减' }
    }
    
    /* App.js */
    
    import React, { Component } from 'react'
    import { Button } from 'antd-mobile';
    import { add, reduce } from './index-redux';
    import { connect } from 'react-redux'
    
    class App extends Component {
      render () {
        let num = this.props.num
        return (
          <div className="App">
            <Button type="primary" inline onClick={() => this.props.reduce()}>-</Button>
            <Button type="warning" inline>{num}</Button>
            <Button type="primary" inline onClick={() => this.props.add()}>+</Button>
          </div>
        )
      }
    }
    
    // 将 state 值赋值给 num 
    const mapStateProps =  (state)=> {
      return { num: state }
    }
    
    const actionCreators = { add, reduce }
    
    // 使用 connect 连接,传入了两个参数,直接挂在到 props 上面,在页面就可以通过 this.props 访问。而且都不用写 dispatch 了
    App = connect(mapStateProps, actionCreators)(App) //将 App 注入 connet 从新生成新的 App
    export default App;
    

1.2.3 装饰器优化connect

1. npm run eject 弹出个性化配置
2. 安装插件
npm install babel-plugin-transform-decorators-legacy  --save-dev
npm install  @babel/plugin-proposal-decorators --save-dev
3. package.jsonbabel 加上plugins 配置
"plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }]
]
  • 将 connect 改写
4. 修改前
const mapStateProps =  (state)=> {
  return { num: state }
}
const actionCreators = { add, reduce }
App = connect(mapStateProps, actionCreators)(App)
5. 等价于(修改后)
const mapStateProps =  (state)=> {
  return { num: state }
}
const actionCreators = { add, reduce }
@connect(mapStateProps, actionCreators)
6. 等价于(修改后)
@connect(
  (state) => {
    return { num: state }	//state 里面属性放到 props
  },
  { add, reduce }	// state 里面方法放到props, 自动 dispatch
)
7. 注意:
  • 如果是 vscode 需要将以下设置修改为 true
"javascript.implicitProjectConfig.experimentalDecorators": true
  • 在使用 @connect 的时候一定要这样导出:
@connect(
  state =>  state,	//state 里面属性放到 props
  { add, reduce, addAsync }	// state 里面方法放到props, 自动 dispatch
)
class App extends Component {
  render () {
    return (
      <div className="App"></div>
    )
  }
}
export default App;

1.2.4 整个 redux 过程

/* index.js */

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
// 引入redux
import { createStore } from 'redux';
import { counter } from './index-redux';
import { Provider } from 'react-redux';

const store = createStore(counter)  //新建 stor
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
/* index-redux */

// 根据老的状态和action生成新的状态 (reducer)
export function counter (state = 0, action) {
  switch (action.type) {
    case '加':
      return state + 1;
    case '减':
      return state - 1;
    default:
      return state
  }
}

// action
export function add () {
  return { type: '加' }
}
export function reduce () {
  return { type: '减' }
}
App.js
import React, { Component } from 'react'
import './App.css';
import { Button } from 'antd-mobile';
import { add, reduce } from './index-redux'
import { connect } from 'react-redux'

@connect(
  (state) => {
    return { num: state }
  },
  { add, reduce }
)
  
class App extends Component {
  render () {
    let num = this.props.num

    return (
      <div className="App">
        <Button type="primary" inline onClick={() => this.props.reduce()}>-</Button>
        <Button type="warning" inline>{num}</Button>
        <Button type="primary" inline onClick={() => this.props.add()}>+</Button>
      </div>
    )
  }
}

export default App;

1.2.5 combineReducers 拆分 reducer

  • 复杂 redux 应用,多个 reducer,用 combineReducers 合并
  • 新建一个 reducer.js 文件
/* reducer.js */
import { Auth } from "./component/LoginComponent/login-redux";
import {Counter } from "./component/CounterComponent/counter-redux";
import { combineReducers } from "redux";

export default combineReducers({Counter, Auth})
  • index.js 中引入使用。
import Reducer from './reducer';

//新建 store
const store = createStore(Reducer)  

ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter>
      <Switch>
        <Route path="/" component={Home}></Route>
        <Route path="/login" component={LoginComponent}></Route>
      </Switch>
    </BrowserRouter>
    <App />
  </Provider>
  , document.getElementById('root'));

1.2.6 异步处理

  • 发起action请求是同步的,当我们发起ajax请求的时候,会立即action而不会等到返回数据以后再action。Redux默认只处理同步,异步任务需要 redux-thunk 中间件
  • 使用 applyMiddleware 开启中间件
  • Action 可以返回函数,使用 dispatch 提交 action
  • 安装:
npm i redux-thunk --save
/* index.js */

import { createStore, applyMiddleware } from 'redux';	// applyMiddleware 开启redux-thunk
import  thunk  from 'redux-thunk';

const store = createStore(Reducer, applyMiddleware(thunk))  
/* index-redux.js  */

export function addAsync () {
    return dispatch=>{
      getData().then(res=>{{
        dispatch(add(res)) // 将返回的数据传过去
      })
    }
}
  • es6 简写
/* index-redux.js  */

export addAsync = ()=> dispatch => {
      getData().then(res=>{{
        dispatch(add(res)) // 将返回的数据传过去
      })
    }

1.2.7 redux-devtools 调试工具

  • 新建 store 的时候判断 window.devToolsExtension
  • 使用 compose 结合 thunkwindow.devToolsExtension
  • 调试窗的 redux 选项卡,实时看到 state
import { createStore, applyMiddleware, compose } from 'redux';
const store = createStore(Reducer, compose(
  applyMiddleware(thunk),
  window.devToolsExtension ? window.devToolsExtension : () => { }))

1.3 Redux 进阶

1.1.1 Redux 项目结构组织方式

  • Ducks 方式

  • reducers、action、types、actions 组合到一个文件中,作为独立模块

  • 划分模块依据:应用状态 State,而不是界面功能。

  • 主要使用

    const LOGIN = "LOGIN"
    const LOGOUT = "LOGOUT"
    
    // Reducer
    let initData = {
      status: false,
      user: "肖定阳",
      password: "123456"
    }
    export function login (state = initData, action) {
      switch (action.type) {
        case LOGIN:
          return { ...state, status: true }
        case LOGOUT:
          return { ...state, status: false }
        default:
          return state
      }
    }
    
    // Action 在使用的时候就不需要一个一个的导入了
    export const actions = {
      log () {
        return { type: LOGIN }
      },
      logout () {
        return { type: LOGOUT }
      }
    }
    

1.1.2 redux的state 设计原则

1. 常见的两种错误
  • 以 API 为设计 State 的依据
  • 以页面 UI 为设计 State 的依据
2. 设计数据库基本原则
  • 数据按照领域分类,存储在不同的表中,不同的表中存储的列数据不能重复
  • 表中每一列的数据都依赖于这张表的主键
  • 表中除了逐渐以外的其他列,互相之间不能有直接依赖关系
3. 设计 redux 的 State 原则
  • 数据按照领域把整个应用的状态按照领域分成若干子 State,子 State 之间不能保存重复的数据
  • 表中 State 以键值对的解构存储数据,以纪录的 key/id 作为纪录的索引 ,纪录中的其他字段都依赖于索引
  • State 中不能保存可以通过已有数据计算而来的数据,即 State中的字段不相互依赖。
  • State 应该尽量扁平化(避免嵌套层级过深)
1.1.6.3 Selector 函数
// selector.js
export const getText = state=>state.text
// 组件中
import selector from './selectors'

const mapStateToProps = state = ({
  text: getText(state)
})
  • selector 还可以将拿到的 state 进行计算在返回
1.1.6.4 前端状态管理思想
  • 状态管理对接口进行二次封装处理

![1554164720007](F:\我的学习\My Study\07-React\assets\1554164720007.png)

  • 软件架构演变
  • 中台层是后端将微服务集合,也就是将小的API聚合为大的中台层

![1554164802253](F:\我的学习\My Study\07-React\assets\1554164802253.png)

1.1.6.5 Middleware

![1554165066437](F:\我的学习\My Study\07-React\assets\1554165066437.png)

// logger.js logger中间件
export default const logger = ({getState, dispatch}) = next => action = {
  console.log(action)
  console.log('next state', getState)
	const result = next(action)
  return result
}
  • 使用
// index.js 中
import logger from "./redux/logger";

const store = createStore(Reducer, applyMiddleware(thunk,logger))
1.1.6.6 Store enhancer
1. 一般结构
function enhancerCreator (){
  return createStore => (...args) =>{
    
  }
}

1.1.1 Fragment 占位符

  • Fragment 占位符并不会被渲染成任何标签元素
import {Fragment} from 'react';
class App extends Component {
    render (){
        return (
        	<Fragment>
            	<div></div>
            	<div></div>
            </Fragment>
        )
    }
}
AI 代码审查Review工具 是一个旨在自动化代码审查流程的工具。它通过集成版本控制系统(如 GitHub 和 GitLab)的 Webhook,利用大型语言模型(LLM)对代码变更进行分析,并将审查意见反馈到相应的 Pull Request 或 Merge Request 中。此外,它还支持将审查结果通知到企业微信等通讯工具。 一个基于 LLM 的自动化代码审查助手。通过 GitHub/GitLab Webhook 监听 PR/MR 变更,调用 AI 分析代码,并将审查意见自动评论到 PR/MR,同时支持多种通知渠道。 主要功能 多平台支持: 集成 GitHub 和 GitLab Webhook,监听 Pull Request / Merge Request 事件。 智能审查模式: 详细审查 (/github_webhook, /gitlab_webhook): AI 对每个变更文件进行分析,旨在找出具体问题。审查意见会以结构化的形式(例如,定位到特定代码行、问题分类、严重程度、分析和建议)逐条评论到 PR/MR。AI 模型会输出 JSON 格式的分析结果,系统再将其转换为多条独立的评论。 通用审查 (/github_webhook_general, /gitlab_webhook_general): AI 对每个变更文件进行整体性分析,并为每个文件生成一个 Markdown 格式的总结性评论。 自动化流程: 自动将 AI 审查意见(详细模式下为多条,通用模式下为每个文件一条)发布到 PR/MR。 在所有文件审查完毕后,自动在 PR/MR 中发布一条总结性评论。 即便 AI 未发现任何值得报告的问题,也会发布相应的友好提示和总结评论。 异步处理审查任务,快速响应 Webhook。 通过 Redis 防止对同一 Commit 的重复审查。 灵活配置: 通过环境变量设置基
【直流微电网】径向直流微电网的状态空间建模与线性化:一种耦合DC-DC变换器状态空间平均模型的方法 (Matlab代码实现)内容概要:本文介绍了径向直流微电网的状态空间建模与线性化方法,重点提出了一种基于耦合DC-DC变换器的状态空间平均模型的建模策略。该方法通过数学建模手段对直流微电网系统进行精确的状态空间描述,并对其进行线性化处理,以便于系统稳定性分析与控制器设计。文中结合Matlab代码实现,展示了建模与仿真过程,有助于研究人员理解和复现相关技术,推动直流微电网系统的动态性能研究与工程应用。; 适合人群:具备电力电子、电力系统或自动化等相关背景,熟悉Matlab/Simulink仿真工具,从事新能源、微电网或智能电网研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握直流微电网的动态建模方法;②学习DC-DC变换器在耦合条件下的状态空间平均建模技巧;③实现系统的线性化分析并支持后续控制器设计(如电压稳定控制、功率分配等);④为科研论文撰写、项目仿真验证提供技术支持与代码参考。; 阅读建议:建议读者结合Matlab代码逐步实践建模流程,重点关注状态变量选取、平均化处理和线性化推导过程,同时可扩展应用于更复杂的直流微电网拓扑结构中,提升系统分析与设计能力。
内容概要:本文介绍了基于物PINN驱动的三维声波波动方程求解(Matlab代码实现)理信息神经网络(PINN)求解三维声波波动方程的Matlab代码实现方法,展示了如何利用PINN技术在无需大量标注数据的情况下,结合物理定律约束进行偏微分方程的数值求解。该方法将神经网络与物理方程深度融合,适用于复杂波动问题的建模与仿真,并提供了完整的Matlab实现方案,便于科研人员理解和复现。此外,文档还列举了多个相关科研方向和技术服务内容,涵盖智能优化算法、机器学习、信号处理、电力系统等多个领域,突出其在科研仿真中的广泛应用价值。; 适合人群:具备一定数学建模基础和Matlab编程能力的研究生、科研人员及工程技术人员,尤其适合从事计算物理、声学仿真、偏微分方程数值解等相关领域的研究人员; 使用场景及目标:①学习并掌握PINN在求解三维声波波动方程中的应用原理与实现方式;②拓展至其他物理系统的建模与仿真,如电磁场、热传导、流体力学等问题;③为科研项目提供可复用的代码框架和技术支持参考; 阅读建议:建议读者结合文中提供的网盘资源下载完整代码,按照目录顺序逐步学习,重点关注PINN网络结构设计、损失函数构建及物理边界条件的嵌入方法,同时可借鉴其他案例提升综合仿真能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaodingyang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值