关于redux:想了解关于-Redux-的这里都有

一、Redux 外围官网是这样解释Redux的:JavaScript 状态容器,提供可预测化的状态治理。 const state = { modleOpen: "yes", btnClicked: "no", btnActiveClass: "active", page: 5, size: 10}Redux 外围概念及工作流程store: 存储状态的容器,JavaScript对象View: 视图,HTML页面Actions: 对象,形容对状态进行怎么的操作Reducers: 函数,操作状态并返回新的状态Redux 计数器案例 ../Redux/src/counter <body> <button id="plus">+</button> <span id="count">0</span> <button id="minus">-</button><script src="https://cdn.bootcdn.net/ajax/libs/redux/4.2.0/redux.min.js"></script><script> // 3 存储默认状态 let initialState = { count: 0 } // 2 创立 reducer 函数 function reducer (state = initialState, action) { // 7 接管 action 并判断 action 的类型 switch (action.type) { case 'increment': return {count : state.count + 1} case 'decrement': return {count : state.count - 1} default: // 初始化是会主动发送一个 init 的 action 用来存储默认的state return state; } } // 1 创立 store 对象, createStore 有第二个参数代表默认值,也就是 reducer 中的 state 参数 let store = Redux.createStore(reducer); // 4 定义 action let increment = { type: 'increment' } let decrement = { type: 'decrement' } // 5 获取按钮并增加事件 document.getElementById('plus').onclick = function() { // 6 触发action store.dispatch(increment); } document.getElementById('minus').onclick = function () { store.dispatch(decrement); } // 8 订阅 store,当store发生变化的时候会执行回调 store.subscribe(() => { // 获取 store 中存储的状态 console.log(store.getState()) document.getElementById('count').innerText = store.getState().count; });</script></body>Redux外围APIconst store = Redux.crateStore(reducer): 创立 Store 容器function reducer (state = initialState, action) {}: 创立用于解决状态的 reducer 函数store.getState(): 获取状态store.subscribe(function(){}): 订阅状态store.dispatch({type: 'discription...'}): 触发action二、React + Redux1.在 React 中不应用 Redux 时遇到的问题在 React 中组件通信的数据流是单向的,顶层组件能够通过props属性向上层组件传递数据,而上层组件不能向下层组件传递数据,要实现上层组件批改数据,须要下层组件传递批改数据办法到上层组件,当我的项目越来越大的时候,组件之间传递数据也就变得越来越艰难。 ...

July 5, 2022 · 8 min · jiezi

关于redux:从-MVC-到-Flux从-Redux-到-Mobx

前端状态治理的工具库纷杂,在开启一个新我的项目的时候不禁让人纠结,该用哪个?其实每个都能达到我的目标,咱们想要的无非就是治理好零碎内的状态,使代码利于保护和拓展,尽可能升高零碎的复杂度。 应用 Vue 的同学可能更违心置信其官网的生态,间接上 vuex/pinia,不必过多纠结。因为我平时应用 React 较多,故就以后利用较宽泛的 Redux、Mobx 俩工具库为例,研读了一番,记录下本人的一些闲言碎语。 留神:以下不会波及到各个库的具体用法,多是探讨各自的设计理念、推崇的模式(patterns),提前阐明,免得耽搁大家工夫。 Redux、Mobx 或多或少都借鉴了 Flux 理念,比方大家常常听到的 “单向数据流” 这项准则最开始就是由 Flux 带入前端畛域的,所以咱们先来聊聊 Flux。 FluxFlux 是由 facebook 团队推出的一种架构理念,并给出一份代码实现。 为什么会有 Flux 的诞生?Facebook 一开始是采纳传统的 MVC 范式进行零碎的开发 但随着业务逻辑的简单,慢慢地发现代码里越来越难去退出新性能,很多状态耦合在了一起,对于状态的解决也耦合在了一起 造成了 FB 团队对 MVC 吐槽最深的两个点: Controller 的中心化不利于扩大,外围是因为 Controller 里须要解决大量简单的对于 Model 更改的逻辑对于 Model 的更改可能来源于各个方向。 可能是开发者自身想对 Model 进行更改、可能是 View 上的某个回调想对 Model 进行更改,可能是一个 Model 的更改引发了另一个 Model 的更改。咱们能够大略总结出,基于 MVC 的数据流向就有三种: Controller -> Model -> ViewController -> Model -> View -> Model -> View ... (loop)Controller -> Model1 -> Model2 -> View1 -> view2 ...并且这三种数据流向在理论业务中还很有可能是交错在一起。 ...

May 18, 2022 · 4 min · jiezi

关于redux:Redux

Redux 外围是js的状态容器 提供可预测化的状态治理 actions:reducers:store应用步骤,以计数器为例 <button id="inc">减少</button><span id="count"></span><button id="dec">缩小</button>创立store对象var store = Redux.createStore(reducer)创立reducer函数, 给定默认初始状态,并匹配action function reducer(state = initState, action) { switch (action.type) { case 'increment': return { ...state, count: state.count + 1 } case 'decrement': return { ...state, count: state.count - 1 } default: return state break }}定义action var increment = { type: 'increment' }var decrement = { type: 'decrement' }触发action store.dispatch(increment)订阅store变动,同步视图变动 store.subscribe(() => { console.log(store.getState())})react-reduxProvider组件 必须位于想要共享状态的组件的顶层,将组件包裹,用于提供store,全局可用 <Provider store={store}> <Children></Provider>connect办法 提供state到指定组件的props映射,同时将store的dispatch办法也放入了props中帮忙咱们订阅store,当store状态产生扭转的时候,从新渲染组件能够通过传递第二个参数,用来简化视图中的dispatch代码// counter.jsimport React from 'react'import { connect } from 'react-redux'import { increment, decrement } from '../store'const Counter = ({ count, inc, dec}) => { return ( <> <button onClick={inc}>+</button> <span>{count}</span> <button onClick={dec}>-</button> </> )}const mapStateToProps = state => ({ a: '10099', count: state.count})// 映射dispatch 办法const mapDispatchToPrps = dispatch => ({ inc() { dispatch(increment) }, dec() { dispatch(decrement) }})// connect的两个办法, 第一个映射state到props,第二个 映射dispatch到props中,能够缩小视图代码export default connect(mapStateToProps, mapDispatchToPrps)(Counter)combineReducer办法将多个reducer文件拆分后,应用redux提供的combineReduver办法进行合并reducerRedux 中间件实质就是一个函数,容许咱们扩大redux应用程序 ...

February 11, 2022 · 3 min · jiezi

关于redux:新的React状态库foca

基于 redux 和 react-redux。仓库地址:https://github.com/foca-js/foca 理念TS First,无TS不编程! 个性模块化开发专一 typescript 极致体验模型主动注册,导出即可应用内置 immer 疾速解决数据智能追踪异步函数的执行状态模型反对公有办法可定制的多引擎数据长久化数据隔离,容许同类状态库并存架构图 在线试玩CodeSandBox 应用定义模型// File: counterModel.tsimport { defineModel } from 'foca';const initialState: { count: number } = { count: 0,};// 毋庸手动注册到store,间接导出到react组件中应用export const counterModel = defineModel('counter', { // 初始值,必填属性,其余属性均可选 initialState, actions: { // state可主动提醒类型 { count: number } plus(state, value: number, double: boolean = false) { // 间接批改状态 state.count += value * (double ? 2 : 1); }, minus(state, value: number) { // 间接返回新状态 return { count: state.count - value }; }, // 公有办法,只能在模型外部被effect办法调用,内部调用则TS报错(属性不存在) _clear(state) { return this.initialState; }, }, effects: { // 异步函数,主动追踪执行状态(loading) async doSomething() { // 调用公有办法 await this._sleep(100); // 疾速解决状态,对于网络申请的数据非常不便 this.setState({ count: 1 }); this.setState((state) => { state.count += 1; }); // 调用action函数解决状态 this.plus(1, true); // 调用effect函数 return this.commonUtil(1); }, // 一般函数 commonUtil(x: number) { return x + 1; }, // 公有办法,只能在模型外部应用,内部调用则TS报错(属性不存在) _sleep(duration: number) { return new Promise((resolve) => { setTimeout(resolve, duration); }); }, }, hooks: { // store初始化实现后触发onInit钩子 onInit() { this.plus(1); console.log(this.state); }, },});在函数组件中应用import { FC, useEffect } from 'react';import { useModel, useLoading } from 'foca';import { counterModel } from './counterModel';const App: FC = () => { // count类型主动提醒 number const { count } = useModel(counterModel); // 仅effects的异步函数能作为参数传入,其余函数TS主动报错 const loading = useLoading(counterModel.doSomething); useEffect(() => { counterModel.doSomething(); }, []); return ( <div onClick={() => counterModel.plus(1)}> {count} {loading ? 'Loading...' : null} </div> );};export default App;在类组件中应用import { Component } from 'react';import { connect, getLoading } from 'foca';import { counterModel } from './counterModel';type Props = ReturnType<typeof mapStateToProps>;class App extends Component<Props> { componentDidMount() { counterModel.doSomething(); } render() { const { count, loading } = this.props; return ( <div onClick={() => counterModel.plus(1)}> {count} {loading ? 'Loading...' : null} </div> ); }};const mapStateToProps = () => { return { count: counterModel.state.count, loading: getLoading(counterModel.doSomething); };}export default connect(mapStateToProps)(App);心愿能成为你下一个我的项目的状态治理计划!喜爱就先star一下吧。仓库地址:https://github.com/foca-js/foca ...

December 23, 2021 · 2 min · jiezi

关于redux:redux

redux 的目录架构import {createStore,applyMiddleware,combineReducers} from 'redux'; import thunk from 'redux-thunk'; import {Provider} from "react-redux" store 1.全局只有一个store通过函数createStore创立 参数是reducer 1.1 createStore(Reducer,applyMiddleware(thunk)); action异步对象 1.2 createStore(combineReducers({key:reducers}),applyMiddleware(thunk)); action异步对象 2. api2.1 diaptch(action)2.2 subacriber(cb) ??有效2.3 getState()组件 1. 须要依据store.getState()获取存储的状态2. 批改须要store.dispatch(action)分发给reducer解决3. redux是能够帮忙你批改state中的状态,然而不会执行render从新渲染界面,render本人调用是有效的 reducer 4. 打工人,收到散发工作立马工作,并且返回最新的state 5. 除了加工,state中的状态的初值也是reducer提供的。会在创立store的时候主动调用reducer dispatch 组件与store沟通的工具人,传递action actionCreator 6. 生产action对象 1.1 同步action对象,是一个js对象,包含type以及data属性 1.2 异步action对象,是一个函数 ?? export const createAddActionAsync = (data,time) =>{ return (dispatch)=>{ setTimeout(()=>{ //store 须要的action 是obj fun无奈让reduces干活没type data // 收到函数(异步工作)的时候 帮忙执行 最初会返回个obj // store须要中间件 redux-thunk 有了它 store能够承受一个函数action dispatch(createAddAction(data)) },time) } };react-redux1. containComponent connect生成containComponent app 中render containComponent传递store2. uiComponent 不可操作redux 只能借助props操作3. store 4. connect const containComponent = connect(mapStateToProps,mapDiapatchToProps)(UI)5. api [传递状态]mapStateToProps(state) 承受container传递的state 返回状态对象作为props传递给UI组件 [传递操作状态]mapDiapatchToProps(dispatch) 承受container传递的dispatch 返回批改(操作)状态的对象作为props传递给UI组件 mapStateToProps以及mapDiapatchToProps react-redux调用机会6. Provider 容器组件是app的子组件容器组件的store是作为参数穿进去的,多个容器就得传递屡次能够应用Provider 入口应用 Provider 会剖析页面有多少容器组件 传递store7. mapDiapatchToProps 能够是一个对象 提供 action react-redux 会主动帮你分发给store 而后调用dispatch给reducers8. 应用react-redux的能够主动监控state的变动,界面会自动更新。9. combineReducers 参数为对象 value是reducer

December 3, 2021 · 1 min · jiezi

关于redux:react篇lesson3reactredux知识点

这一节美容不是很难次要是react-reudx的外围局部,这部分其实redux也有,就是Provider、connect、bindActionCreators等几个罕用的API的实现。间接上外围代码import React, { useLayoutEffect, useReducer, useCallback, useContext } from 'react';const useForceUpdata = () => { const [_, forceUpdata] = useReducer(x => x + 1, 0,); const upDate = useCallback(() => forceUpdata(), []) return upDate};const Cunsumer = ({ store }, mapStateToProps, mapDispatchToProps, WarppedComponent, props) => { // stateProps其实就是以所有state为参数,mapStateProps执行的后果 const forceUpdata = useForceUpdata() const stateProps = mapStateToProps(store.getStore()); // dispatchProps须要麻烦一点因为会有两种状况 // 第一种mapDispatchProps是函数 // 第二种mapDispatchProps是对象 let dispatchProps = { dispatch: store.dispacth }; // 这里补充一下最精确的判断数据类型的办法:Object.prototype.toString.call(mapDispatchProps) if (typeof mapDispatchToProps === "function") { dispatchProps = mapDispatchToProps(store.dispach) } else if (typeof mapDispatchToProps === "object") { dispatchProps = bindActionCreators(mapDispatchToProps, store.dispach) } // * 重点 这里是必须要写订阅的不然咱们代码跑起来不会报错然而页面也不会刷新, // * redux 只是一个状态存储库,不具备主动刷新页面的性能,须要咱们自行编写订阅代码 // * 这里应用useLayoutEffect而不是useEffect,是因为useLayoutEffect在dom变更后就开始同步执行,而useEffect有提早 useLayoutEffect(() => { const unsubscribe = store.subscribe(() => { forceUpdata() }) return () => { unsubscribe() }; }, [store]) return <WarppedComponent {...props} {...stateProps} {...dispatchProps} />};// 创立Contextconst Context = React.createContext();// 导出Provider组件export const Provider = ({ store, children }) => { return <Context.Provider value={store}>{children}</Context.Provider>};export const connect = ({ mapStateToProps, mapDispatchToProps }) => WarppedComponent => props => { // 子孙组件生产父级传下来的value return <Context.Cunsumer> {(value) => Cunsumer(value, mapStateToProps, mapDispatchToProps, WarppedComponent, props)} </Context.Cunsumer>}export const bindActionCreators = (data, dispacth) => { let obj = {} for (const key in data) { obj[key] = dispacth((...arg) => obj[key](...arg)) } return obj};export const useDispatch = () => { const store = useContext(Context) // 间接返回store中的dispatch即可 return store.dispatch}export const useSelector = (selctor) => { const store = useContext(Context) // 这里一样是要订阅一下不然页面不会更新 useLayoutEffect(() => { const unsubscribe = store.subscribe(() => { forceUpdata() }) return () => unsubscribe() }, [store]) return selctor(store.getStore())}以上便是几个罕用API的根本实现. ...

November 24, 2021 · 2 min · jiezi

关于redux:react篇lesson2redux知识点

提起redux小伙伴们应该都不生疏,驰名的第三方状态治理库,也是很多小伙伴进阶路上必然攻克的源码之一。Redux 除了和 React 一起用外,还反对其它界面库。 它体小精悍(只有2kB,包含依赖)。明天咱们就来说说redux学习中须要重点学习的货色; 三大准则Redux 能够用这三个根本准则来形容: 繁多数据源整个利用的 state 被贮存在一棵 object tree 中,并且这个 object tree 只存在于惟一一个 store 中。 State 是只读的惟一扭转 state 的办法就是触发 action,action 是一个用于形容已产生事件的一般对象。 应用纯函数来执行批改为了形容 action 如何扭转 state tree ,你须要编写 reducers。 应用其实redux应用起来大抵能够分为一下几步骤: 申明store文件(寄存state)// store.jsimport { createStore } from 'redux';import reducer from "./reducer.js";const store = createStore(reducer);export default store;申明reducer.js文件(批改state)申明的reducer文件次要是为了批改保留的state export default const counter = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1; case 'DECREMENT': return state - 1; default: return state; }};dispatch触发action动作、subscribe订阅以及unsubscribe勾销订阅store.dispatch({ type: 'INCREMENT' });const unsubscribe = store.subscribe(()=> {});知识点以上是咱们须要理解的根底,其实redux摊开了说白了也没有什么神秘的就是一个第三方文件保留state,用特定action去触发批改,咱们须要理解的真正外围是redux对于createStore中参数enhancer的解决以及applyMiddleware的实现,这才是redux的外围; ...

November 24, 2021 · 2 min · jiezi

关于redux:Redux-的基本使用

1.外围概念1.什么是Redux?Redux是一个治理状态(数据)的容器,提供了可预测的状态治理 2.什么是可预测的状态治理?数据 在什么时候, 因为什么, 产生了什么扭转,都是能够管制和追踪的,咱们就称之为预测的状态治理 3.为什么要应用Redux?React是通过数据驱动界面更新的,React负责更新界面, 而咱们负责管理数据默认状况下咱们能够在每个组件中治理本人的状态, 然而当初前端应用程序曾经变得越来越简单状态之间可能存在依赖关系(父子、共享等),一个状态的变动会引起另一个状态的变动所以当应用程序简单的时候, 状态在什么时候扭转,因为什么扭转,产生了什么扭转,就会变得十分难以管制和追踪所以当应用程序简单的时候,咱们想很好的治理、保护、追踪、管制状态时, 咱们就须要应用Redux 4.Redux核心理念通过 store 来 保留数据通过 action 来 批改数据通过 reducer 来 关联 store 和 action 2.三大准则1.Redux三大准则繁多数据源整个应用程序的state只存储在一个 store 中Redux并没有强制让咱们不能创立多个Store,然而那样做并不利于数据的保护繁多的数据源能够让整个应用程序的state变得不便保护、追踪、批改State是只读的惟一批改State的办法肯定是触发action,不要试图在其余中央通过任何的形式来批改State这样就确保了View或网络申请都不能间接批改state,它们只能通过action来形容本人想要如何批改stat;这样能够保障所有的批改都被集中化解决,并且依照严格的程序来执行,所以不须要放心race condition(竟态)的问题;应用纯函数来执行批改通过reducer将 旧state和 action分割在一起,并且返回一个新的State:随着应用程序的复杂度减少,咱们能够将reducer拆分成多个小的reducers,别离操作不同state tree的一部分然而所有的reducer都应该是纯函数,不能产生任何的副作用 2.什么是纯函数返回后果只依赖于它的参数,并且在执行过程外面没有副作用 // 纯函数function sum(num1, num2){ return num1 + num2;}// 非纯函数let num1 = 10;function sum(num2){ return num1 + num2;}// 纯函数const num1 = 10;function sum(num2){ return num1 + num2;}3.根本应用筹备工作创立 demo 目录cd demonpm init -y #初始化一个node我的项目npm install --save redux #装置reduxredux的应用store.subscribe() #监听函数(一旦 state 发生变化,就主动执行这个函数) ...

November 12, 2021 · 7 min · jiezi

关于redux:Redux学习笔记

从一个初学者的角度来剖析: Redux是干啥用的呢?学习Redux之前要理解什么?理论我的项目中如何用到(针对小白)状态治理和hooks有什么关系? 问题3:理论我的项目中如何用到(针对小白)实现这样一个性能:点击Increase的话右边数字加1,点击Decrease每次减1 首先创立这个组件 class Counter extends Component { render() { const { value, onIncreaseClick, onDecreaseClick } = this.props return ( <div> <span>{value}</span> <button onClick={onIncreaseClick}>Increase</button> <button onClick={onDecreaseClick}>Decrease</button> </div> ) }}Action :Action 是把数据从利用传到 store 的有效载荷。它是 store 数据的惟一起源。一般来说你会通过 store.dispatch() 将 action 传到 store。Action 实质上是 JavaScript 一般对象。咱们约定,action 内必须应用一个字符串类型的 type 字段来示意将要执行的动作。 // Actionconst increaseAction = { type: 'increase' } const decreaseAction = { type: 'decrease' } Reducers : Reducers 指定了利用状态的变动如何响应 actions 并发送到 store 的,记住 actions 只是形容了有事件产生了这一事实,并没有形容利用如何更新 state。 ...

September 15, 2021 · 2 min · jiezi

关于redux:函数合成compose的多种实现原理

// 责任链模型(一个接一个执行) const fn1 = (x, y) => x + y;const fn2 = (z) => z * z;// 失常组合 const compose = (fn1, ...other) => (...args) => { let ret = fn1(...args); other.forEach(item => { ret = item(ret); }); return ret;}// redux 中间件组合形式 const reduxCompose = (...fns) => fns.reduce((a, b) => (...args) => b(a(...args)))const fn = reduxCompose(fn1, fn2);console.log(fn(1, 2));// 洋葱圈模型(一半一半执行) const koaCompose = (middlewares) => { return function () { return dispatch(0); function dispatch(idx) { const fn = middlewares[idx]; if (!fn) { return Promise.resolve(); } return Promise.resolve( fn(function next() { return dispatch(idx + 1) }) ) } }};async function func1(next) { console.log("func1"); await next(); console.log("func1 end");}async function func2(next) { console.log("func2"); await delay(); await next(); console.log("func2 end");}async function func3(next) { console.log("func3");}async function delay() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, 2000); })}const middlewares = [func1, func2, func3];const finaFn = koaCompose(middlewares);finaFn()

August 30, 2021 · 1 min · jiezi

关于redux:redux总结

Redux 是什么Redux is a predictable state container for JavaScript apps Redux概念store: 利用数据的存储核心action: 利用数据的扭转的形容reducer: 决定利用数据新状态的函数,接管利用之前的状态和一个 action 返回数据的新状态。state: 状态middleware: redux 提供中间件的形式,实现一些 流程的自定义管制,同时造成其插件体系。 流程 环境筹备npx create-react-app cracd cra npm start在 cra我的项目中装置redux yarn add reduxredux整体感知// reducerconst weight = (state = 160, action) => { switch (action.type) { case 'eat': return state + 10 case 'hungry': return state - 10 default: return 160 }}const store = createStore(weight)console.log(store.getState())store.dispatch({ type: 'eat' })console.log('我吃了一些事物')console.log(store.getState())console.log('我饿了好几天')store.dispatch({ type: 'hungry' })console.log(store.getState())console.log('我又饿了好几天')store.dispatch({ type: 'hungry' })console.log(store.getState())reducer 外面应用switch语句依据传入的类型,输入新的状态把reducer 传入 createStore(weight)通过 dispatch 传入不同的类型,扭转状态state。store.dispatch({ type: 'hungry' })通过 store.getState() 获取以后的状态 ...

June 28, 2021 · 1 min · jiezi

关于redux:redux中使用TS每次都要定义一遍类型

umi架构下:ts我的项目中redux定义module每次都要写一遍类型定义麻烦得很 typing文件夹下创立Redux.d.ts申明文件 import type { Effect, Subscription, ImmerReducer } from 'umi';declare module MyRedux { // model type Models<T> = { namespace?: string; state: T; effects: Record<string, Effect>; reducers: Record<string, ImmerReducer<T>>; subscriptions?: Record<string, Subscription>; };}// 导出成模块,再全局导出MyRedux,这样应用就不必再import type { Redux } from '@/typings/redux'; 了export = MyRedux; // 因为应用了import,此文件变成部分模块,其余中央应用只能import导入(import type { Redux } from '@/typings/redux';)能力应用export as namespace MyRedux;如何应用models文件夹下创立staff.ts type StaffSettingState = { staff: Record<string, never>; };const StaffSettingsModel: MyRedux.Models<StaffSettingState> = { namespace: 'staffSettingsModel', state: { staff: {} }, effects: {}, reducers: {},};export default StaffSettingsModel;

May 17, 2021 · 1 min · jiezi

关于redux:Redux

redux=>将Flux与函数式编程联合到一起,是一种web架构的解决方案 Redux应用场景某个组件的状态,须要共享某个状态须要在任何中央都能够拿到一个组件须要扭转全局状态一个组件须要扭转另一个组件的状态

April 14, 2021 · 1 min · jiezi

关于redux:Redux-理解-combineReducers

最近在我的项目中应用 redux 时遇到一个问题:应用多个 reducer 治理状态(如 ruducerA,reducerB),当通过 action 更新数据时,以后的 reducerA 数据更新胜利,但另一个 reducerB 数据被初始化。 这个行为让我十分蛊惑,排查了很久, 一度找不到下手点。代码如下: APP.js const rootReducer = combineReducers({ RudecerA, RudecerB,}); const store = createStore( rootReducer);  export default function App(props) { return ( <Provider store={store}> <Router {...props} /> </Provider> );}reducerB.js export function ReducerB( state = initState, action, ) { switch (action.type) { case UPDATE_RECORD_DATA: return { ...state, recordData: action.payload }; case DELETE_RECORD_DATA: return { ...state, recordData: initRecordData }; default: return initState; }}解决办法起初在官网文档看到对于 combineReducer 的介绍及留神点: ...

March 6, 2021 · 1 min · jiezi

关于redux:中间件

什么是中间件?中间件就是插在源到指标之间的一段逻辑(个别为函数,比方redux) redux中源为页面,指标为store中的state,通过dispatch将页面中的数据反映到store中 koa中源为request,指标为response, redux中在dispatch数据到store只调用了dispatch这个函数,所以只能对这个函数进行革新,两头去插入中间件。 为什么redux须要中间件?dispatch函数第一句话: if (!isPlainObject(action)) { throw new Error( 'Actions must be plain objects. ' + 'Use custom middleware for async actions.' ) }isPlainObject函数的目标是查看action是不是对象字面量或者new object()结构进去的对象,其余的比方action为函数,redux间接报错。比方异步申请,须要将从接口申请到的数据放到redux。咱们能够间接发动异步申请,而后将数据dispacth到redux里redux@4.0.0 shopping-cart actions/index.js export const checkout = products => (dispatch, getState) => { const { cart } = getState() dispatch({ type: types.CHECKOUT_REQUEST }) shop.buyProducts(products, () => { dispatch({ type: types.CHECKOUT_SUCCESS, cart }) })}为了对立写异步申请,将申请函数放在一个文件里,这样不会显得芜杂。然而dispatch跟getState怎么拿到,connect后能够拿到dispatch,getState拿不到,只能通过mapStateToProps传递state.这么操作比拟麻烦,在中间件中对立解决就不须要每次调用传递dispatch getState。怎么对一个函数函数革新 插入中间件? 深刻了解洋葱模型中间件机制Koa 框架教程

October 16, 2020 · 1 min · jiezi

关于redux:重学reactredux

一、redux应用redux应用和之前的useReducer应用比拟相似(详情请看 重学react——context/reducer 一文) // store.tsimport { createStore, applyMiddleware, combineReducers } from 'redux';import logger from 'redux-logger'; // 中间件import thunk from 'redux-thunk'; // 中间件export interface IState { name: string, age: number, sons: any[]}export const state: IState = { name: 'lihaixing', age: 32, sons: []};export type Action = { type?: string; data?: any;};export function reducer(state: IState | undefined, action: Action) { if (!action.type && !action.data) { return { ...state, ...action }; } switch (action.type) { case 'update': return { ...state, ...action.data }; default: return state; }}// createStore与useReducer相似export const store = createStore(reducer, state, applyMiddleware(logger, thunk));// contaner.tsximport React, { useReducer } from 'react';// react-redux的作用和react的context相似import {Provider} from 'react-redux'; import { store } from './store';import Com1 from './comp1'import Com2 from './comp2'const IndexView = () => { return <Provider store={store}> <Com1 /> <Com2 /> </Provider>};export default IndexView;// com1.tsximport React, { useContext } from 'react';import { IState } from './index';// connect和useContext的作用相似import { connect } from 'react-redux';const IndexView = (props: any) => { const {name, age, sons} = props.state; const {update, asyncUpdate} = props; const setAge = () => { // dispatch({type: 'update', data: {age: age + 1}}); update({age: age + 1}); }; const setSons = () => { // setTimeout(()=>{ // update({sons: [...sons, 1]}); // }) asyncUpdate({sons: [...sons, 1]}); }; return <div> {name} <br/> {age} <br/> {sons} <br/> <button onClick={setAge}>按钮age</button> <button onClick={setSons}>按钮sons</button> </div>;};const mapStateToProps = (state: IState) => ({state});const mapDispatchToProps = { update: (data: any) => ({type: 'update', data}), // 异步返回的是函数 asyncUpdate: (data: any) => (dispatch: any) => { setTimeout(() => { dispatch({type: 'update', data}); },1000); }};// 不传第二个参数,props会有dispatchexport default connect(mapStateToProps, mapDispatchToProps)(IndexView);从上述咱们能够将redux和useReducer/useContext作比照重学react——context/reducer ...

September 1, 2020 · 3 min · jiezi

关于redux:TS-Redux-的一些感想

很久没写文章了,始终在奉献开源框架和一些库,也不善于写文章,看我已往的文章,全都是干瘪瘪的,没有半点废话。这次算是写个软文吧,实话实说,也没期待会有多少人看。 链接先放着:https://github.com/redux-model/redux-model 记得2016年刚守业失败进去找工作,找了一家教育类的互联网公司(当初也是)。这家公司用的是es6 + react + redux + webpack的前端架构。而我守业期间,还在写 es3 + jquery,钻研各种构造函数/继承/原型 等一些比拟底层的货色。所以进了新公司,算是解放了吧,有种从2g网络迁徙到4g网络的感觉,仙气飘飘。 那时候的redux,哇哦,先写上3个actionType类型(申请须要3个状态),再写一个action和一个reducer,reducer里写上3个case,别离对应3个actionType。如果Reducer数据比较复杂,那就是各种Object.assign了。所以在写了两个月之后,俨然发现我是不是在始终写模板文件啊?感觉每次都是似曾相识?但也没啥方法,抽也没法抽,毕竟对redux理解不够深刻。我共事的做法是写一个代码片段,每次须要的时候主动生成,而后修修改改完事。 断断续续写了2年左右原生的Redux,直到2018年,Typescript曾经有点纸包不住火了,我也被点燃了,所以尝试了好几次,总想把我的项目转到ts去,于是网上各种搜寻最佳实际案例,每种都尝试过来,各种崎岖。断断续续地,终于在2018年底给安顿上了! 写了第一版的Ts + React + Redux,还算称心,总算都有类型了,数据能够精准追踪。当初是2019年,也快30岁了,你晓得的,人老了,就写不动了,须要正当地偷懒,须要准时上班 心里其实早有疙瘩,这Redux模板是时候给治一治了。于是有了第一版的Redux-Model,目标很明确,干掉actionType,把action和reducer整合在一起,不再写3个文件。所以第一版本的模型,分的很细,一个模型只蕴含一个action,当咱们有多个模型须要作用到同一个reducer时,reducer须要附在其中一个模型里。 现在,Redux-Model曾经升到了8.0了,框架早已稳定下来,一个模型能够写无数个action和一个reducer,数据变动也高深莫测。所以我最后的那个TS我的项目,至多大规模重构了5次的模型,每次都是几百个模型文件变更。真正地稳固应该是在6.0的时候,因为这个版本解决了一个类型主动反推导方面的大难题,这个问题至多花了我3个月的上班时间去冥思和尝试才胜利。那时候,公司里有3个团队曾经曾经在用我的模型框架(包含TS也是我在公司里推广的,当初所有团队都曾经承受TS了),想让他们降级,就必须一个一个帮忙升,还真是有点不好意思了。 付出总是有回报的,当初在去采访那几个团队,对框架的评估是完满,这不也是我所谋求的吗? 框架虽好,但没有大厂背景,没有集体光环,想推广起来几乎和做梦一样----想的美。推广过一段时间,大部分是在群里,不过换来的都是冷言冷语,什么 dva不香吗?mobx不香吗? 这些框架难道我没尝试过吗,就你晓得香?都是给JS用户设计的,对TS不太敌对,至多还没达到我的要求,所以我才要写这么一个框架,为TS量身定制的Redux框架。七夕那天,我在一个聊了挺久的群发了一个框架链接(加群大半年,总共没发超过5次),当场就被群主骂了,我没法承受,因为他感觉我推广这个是为了找到更好的工作?这种羞辱开源精力的事,我没法承受,退群了。预先群主还要再私发我一条微信:无利不起早?? 我没有回复,没必要了,不与君子辩论。 不是每个人都为找工作而写代码。趣味是个好货色,高考完结,他人都在网吧打游戏,我在书店背了几段html脚本去网吧运行,给小伙伴看成果。在共事眼里,我就是那种聊到代码就两眼放光的人。而开源,是为了欠缺生态,让大家有更好的抉择。当然了,某种程度也是想证实本人能力ok,码痴不都这样吗? 感兴趣的TS铁粉,举荐应用。JS用户不举荐应用,因为是TS定制的,但欢送star,让更多的人晓得这个库,毕竟我太缺光环了。 好不好用,您去看看Readme,而后demo运行看看就晓得什么叫手中无TS,心中有TS。我不去吹,因为自信。 https://github.com/redux-model/redux-model

August 27, 2020 · 1 min · jiezi

关于redux:关于redux的一些学习笔记

redux是用于治理react状态的一个状态管理器 外围有三大部分组成--action、reducer、store action:是触发state扭转的状态,是一般的js对象,语义作用; const addAction = { type: 'ADD_ITEM', text: 'to add a new item'}reducer:纯函数 传递action以触发state扭转的函数,传入state和action,做一些合乎action的解决,创立state的正本,并返回这个正本。 function todoApp(state, action) { switch(action.type){ case 'ADD_ITEM': return Object.assign({},state,{ ...state.todos, {text: action.text, completed: true} }); }}store:存储state的中央。办法:getState():获取statedispatch(action): 更新statesubscribe(listener): 注册监听器,返回一个函数,调用此函数可登记监听器。 创立store: import { createStore } from 'redux';import rodoApp from './reducers';let store = createStore(todoApp);单向数据流--数据生命周期:调用store.dispath(action);redux store会主动调用传入的reducer函数;根reducer会把多个子reducer输入合并成一个繁多的reducer树;redux store保留根reducer返回的残缺state树,该state树就是下一个state,所有调用store.subscribe(listener)的监听器都将被调用,在监听器中能够通过调用store.getState()来获取以后的state。 配合react(redux自身和react没有关系)装置react绑定库:npm install --save react-redux其基于react的容器组件与UI组件相拆散的思维来开发。 UI组件Container组件是否间接应用Redux否是数据起源props监听redux state数据批改从props调用回调函数向redux派发action调用形式手动通常由react redux生成作用展现骨架、款式数据获取、状态更新容器组件用connect()办法生成。【该办法外部做了一些性能优化,防止了很多不必要的rerender】其本质是通过store.subscribe()从redux state树中读取局部数据,并通过props将这些数据传给对应的UI组件。 connect()的用法 import { connect } from 'react-redux';connect(mapStateToProps, mapDispathToProps)(TodoList);const getVisibleTodos = (todos, filter) => { switch(filter) { case 'SHOW_COMPLETED': return todos.filter(...) // ... }}const mapStateToProps = state => { return { todos: getVisibleTodos(state.todos, state.visibilityFilter) }}const mapDispathToProps = dispatch => { return { onTodoClick: id => { dispatch(toggleTodo(id)) } }}mapStateToProps: 该函数用于指定如何将以后的redux store的state映射到对应UI组件的props中。mapDispathToProps:该函数接管dispatch()办法并返回冀望注入到UI组件props中的回调函数。 ...

August 20, 2020 · 1 min · jiezi

手写实现reactredux的Hook-API

前言本文章的内容,不会对根底的Hook API进行解说,比方(能够从官网间接看到)react Hook API:https://zh-hans.reactjs.org/d... useStateuseEffectuseContext间接放一个demo,自行学习吧。也不是很难import React,{ useState,useEffect } from 'react'export default function HookPage(){ const [date, setDate]=useState(new Date()) const [count, setCount] = useState(0) // 一个函数能够有多个 useEffect useEffect(() => { console.log('数字产生扭转:' ,count) }, [count]); // 有依赖项,是count; 所以每次点击更改count的时候进行更新,就相当于生命周期update useEffect(()=>{ console.log('setDate') const timer = setInterval(()=>{ setDate(new Date()) },1000) // 革除定时器,相当于申明周期 willUnmount return()=>clearInterval(timer) },[]) // 没有依赖项,就相当于DidMount return( <div> <h3> HookPage </h3> <div> <span> 数字:{count} </span> <button onClick={()=>setCount(count+1)}>减少</button> </div> <div> 当初工夫:{date.toLocaleTimeString()} </div> </div> )}所有的react API 在官网都说的很不错了,我感觉看官网的介绍就曾经很明确了,而且迭代版本必定也是最新的,所以本章的内容次要是联合实战和我的项目,进行简略的应用阐明,之后在进行,手动实现react-redux的Hook API;useReducer略微说下这个API,因为 我在应用init的时候,忽略了一个return,导致我查了半天。 ...

July 12, 2020 · 3 min · jiezi

reactRedux的API的使用及原理讲解和手动实现方法

对react-Redux的利用与了解在平时中,咱们间接去应用Redux,须要每个页面都须要引入store,执行getState()来获取到值,以及须要每次都进行订阅和勾销订阅。保护起来不不便 import React,{Component} from 'react'import store from '../store'export default class ReactRedux extends Component{ constructor(){ super() } componentDidMount(){// 挂载 this.unsubscribe=store.subscribe(()=>{ this.forceUpdate() }) } add=()=>{ store.dispatch({type:'ADD',payload:10}) } componentWillUnmount(){// 卸载 if(this.unsubscribe){ this.unsubscribe() } } render(){ return( <div> <h3>ReactRedux-page</h3> <div> <p>{store.getState()}</p> <button onClick={this.add} > add </button> </div> </div> ) }}从而引入react-Redux,Provider这个性能;在根目录下间接引入store;src/index.js import React from 'react';import ReactDOM from 'react-dom';import './index.css';import ReactRedux from './pages/ReactReduxPage'import {Provider} from 'react-redux'import store from './store'ReactDOM.render( <Provider store={store}> <ReactRedux /> </Provider> , document.getElementById('root'));class组建在应用connect引入import {connect} from 'react-redux'connect一共有三个参数:state, dispatch,mergeProps(将props进行合并)@connect( (state)=>({num:state}))class ReactRedux extends Component{ render(){ console.log(this.props) return( <div></div> ) }}@connect是装璜器的应用,或者能够export default connect()(class ...);装璜器的应用能够本人查下不做重点解说。打印this.props ...

July 11, 2020 · 4 min · jiezi

手写实现Redux功能applyMiddleware中间件

Rredux是什么?Redux是JavaScript应⽤用的状态容器器。它保证程序⾏行行为⼀一致性且易易于测试。 React Conponent: 我们开发的的React组建;当组建的内容要发生改变的时候;我们要发起一个dispatch,dispatch去派发action,action里面会包裹{type,paylod}Reducer就是制定修改规则的纯函数;接收一个旧的state,和action返回一个新的state 永远不要在 reducer ⾥做这些操作: 修改传⼊参数;执⾏有副作⽤的操作,如API请求和路由跳转;调⽤⾮纯函数,如Date.now()或 Math.random()。共享的数据存储在Store里面(state)更新完的数据Store传给组建安装Rredux npm install ReaduxReadux的使用创建store和制定reducers规则src/store/index.js import { createStore } from 'redux'// 定义state初始化和修改规则function createReducer(store=1,{type,payload=1}){ // type: action 的修改规则,用于switch判断 // paylod,当发起dispatch传进来的参数 console.log(store, 'store') switch (type) { case 'ADD': // 加法规则 return store+payload break; case 'MINUS': // 减法规则 return store-payload break; default: // 默认导出规则 return store break; }}const store = createStore(createReducer) // 定义store里面的修改规则export default store写一个组建src/pages/ReaduxPage.js import React, {Component} from 'react'import store from "../store/index";export default class ReaduxPage extends Component{ constructor(){ super() } render(){ return( <div> <h3> ReaduxPage </h3> <div> 获取到store里面设置的state <p>{store.getState()}</p> </div> 点击按钮,触发dispatch <button onClick={()=>store.dispatch({type:'ADD'})}> 点击增加 </button> </div> ) }}再或者改成,方法调用的方式 ...

July 5, 2020 · 4 min · jiezi