react_结合 redux - 高阶函数 - 高阶组件 - 前端、后台项目打包运行


Redux 独立的集中式状态管理 js 库 - 参见 My Git
不是 react 库,可以与 angular、vue 配合使用,通常和 react 用
yarn add redux
import {createStore} from "redux"
const store = createStore(myCounter); // 1. 核心 API - 参数是 reducer 函数---> 根据现有的状态及 action 返回一个新的状态,给 store 管理
import {INCREMENT, DECREMENT} from "./action-types" // 有几个 case,就要定义几个 action 工厂
export default function myCounter(state=0, action){ // 由 store 内部调用,初始值为 0 ./redux/reducers
switch(action.type){ // action 一定要有一个 type 属性
case INCREMENT:{return state+action.numbe;brack;}
case INCREMENT:{return state+action.numbe;brack;}
default: return state
}
}
<App store={store}
import {INCREMENT, DECREMENT} from "./action-types"
export const INCREMENT = "increment";
export const DECREMENT = "decrement";
import * as actions from "../redux/actions";
this.props.store.dispatch(actions.increment(number)); // action creator 产生一个 action 对象,然后 dispatch 这个行为 action
// 虽然等同于 this.props.store.dispatch({type: INCREMENT, number}); 但是一般不这么做
// 工厂函数 - 每次调用,返回一个新的对象 - 每次都返回一个 actions

this.props.store.getState();
- action
如果是 对象,则是 同步 action ---- 返回一个对象,描述行为、state 参数
export const menuTitle = (menuTitle)=>({tyle: SETMENUTITLE, data: menuTitle})
如果是 函数,则是 异步 action
返回一个 函数,该函数接收一个 dispatch 参数
该函数内部进行异步操作,有了结果以后,再 dispatch 同步 action
export const login = ()=>{
return dispatch=>{
// 1. 执行异步代码
const result = await requestLogin(username, password);
// 2. 分发同步 action
if(result.status === 0){
}else{
}
}
}
- reducer
根据现有的 state 和 action 生成新的 state
- const store = createStore(myReducer) // 根据 n 个现有需要管理的 state 和 action 返回一个新的 state,给 store 集中管理
- store 最核心的 管理对象---- 与 react 的交互就是 读 和 更新
存储状态数据的对象
维护着 state 和 reducer
核心方法
- 获取状态 store.getState()
- 更新状态 store.dispatch(action-creator)
对象 action
- 必须有 type 标识属性,值为字符串
- 可选数据属性,值为任意类型
- 订阅一个监听函数 subscribe(listener)
什么时候用 redux?
某个组件的状态需要共享
一个组件需要改变全局状态
一个组件需要改变另一个组件的状态
总体原则: 能不用就不用,如果不用比较吃力才考虑使用
不用 redux 时的集中状态管理?
将多个组件的共用状态放在共同的父组件中
将状态的相关方法定义在与状态相同的组件中
官方实例分析?

redux 编程:
---------------------------------------------------------------------------------------------------------
src/redux/store.js
import {createStore} from "redux"
import reducer from "./reducer"
export default creareStore(reducer); // 创建 store 对象,内部会第一次自调用 reducer 函数得到一个初始的状态值进行保存

---------------------------------------------------------------------------------------------------------
src/redux/reducer.js
import {INCREMENT, DECREMENT} form "./action-types"
export default function count(state=1 action){ // 管理 count 就可以叫 count,state 本身就是要管理的数据,第一次展示显示 1
switch(action.type){
case INCREMENT:{return state+action.number;}
case INCREMENT:{return state-action.number;}
default: return state; // 不做任何处理
}
}
---------------------------------------------------------------------------------------------------------
src/redux/actions.js // 包含 n 个 action-creator 函数
import {INCREMENT, DECREMENT} form "./action-types"
export const increate = (number)=>({type: INCREMENT, number});
export const decreate = (number)=>({type: DECREMENT, number});
---------------------------------------------------------------------------------------------------------
src/redux/action-types.js // 多个 js 共用
export const INCREMENT = "increment";
export const DECREMENT = "decrement";
---------------------------------------------------------------------------------------------------------
src/index.js
import React from "react"
import ReactDOM from "react-dom"
import App from "./App.jsx"
import store from "./redux/store"
ReactDOM.render(<App store={store} />, document.getElementById("root"));
store.subscribe(()=>{
ReactDOM.ummountComponentAtNode(document.getElementById("root")); // 先卸载原来的组件
ReactDOM.render(<App store={store} />, document.getElementById("root"));
})
---------------------------------------------------------------------------------------------------------
src/App.jsx
import React, {PureComponent} from "react"
import * as actions from "./redux/actions"
export default class App extends PureComponent{
increment = ()=>{
const number = +this.refs.numberSelect.value;
this.props.store,dispatch(actions.increment(number));
}
decrement = ()=>{
const number = +this.refs.numberSelect.value;
this.props.store,dispatch(actions.decrement(number));
}
render(){
const count = this.props.store.getState();
}
}
问题: react 与 redux 耦合度太强了,直接使用了 store
解决: 使用 react 的插件库 react-redux ---- 简化 react 中使用 redux
----------------------------------------- react 与 redux 的连接库--------------------------------------------
Provider
向所有容器组件提供 store
connect(生成 容器组件,负责向 UI 组件传递标签属性
第一参数: 函数 ---- 一般属性从 state 中获取
state=>({title: state.menuTitle})
第二参数: 原始函数/简写对象{actionCreator1, action2}---- 函数属性,执行 dispatch 分发 action-creator
)(UI组件)
---------------------------------------------------------
src/index.js
import React from "react"
import ReactDOM from "react-dom"
import App from "./App.jsx"
import store from "./redux/store"
import {Provider} from "react-redux"
-------------------------------------------------------------------------------------------------------------------
src/App.jsx
import React, {PureComponent} from "react"
import {connect} from 'react-redux'
imoprt Counter from "./components/Counter"
imoprt {increment, decrement]} from "./redux/actions"
function mapStateToProps(state){ // 读取 state 数据,并将其映射成 UI 组件的一般属性
return {count: state}
}
function mapDispatchToProps(dispatch){ // 为 UI 组件映射函数属性,函数内部必须 dispatch,分发 action,产生新的 state,重新 render
return {
incremrnt: number=>dispatch(increment(number))
decremrnt: number=>dispatch(decrement(number))
}
}
export default connect(
mapStateToProps, // 用来确定向 UI 组件传递哪一些一般属性 count
mapDispatchToProps // 用来确定向 UI 组件传递哪些函数属性 increment、decrement
)(Counter) // 用 connect 函数包装一下 App 组件,返回一个新的组件对象

-------------------------------------------------------------------------------------------------------------------
src/components/Counter.jsx
1
react-redux 将组件分为
UI 组件
不会使用任何 redux 相关的语法
最终,值还是要被 store 管理的 ,getState()、dispatch()、
容器组件: 通过 connect 包装 UI 组件生成的组件,内部可以看见 store
1. 向 UI 组件传递一般属性,属性值 会以 state 传递
传递 状态 以及操作 store 的相关函数到 reducer 中
2. 属性值函数内部必然执行 dispatch 去分发 action

最终的简洁写法-------------------------------------------------------------------------------------

redux 异步编程
下载 异步中间件 yarn add redux-thunk
store.js
import thunk from "redux-thunk" // 中间件,扩展 redux 使其可以 action-creator 可以返回 函数
import {createStore, applyMiddleware} from "redux"
import reducer from "./reducer"
export default createStore(reducer, applyMiddleware(thunk));
actions.js 红中增加 异步 action
返回的是一个函数,函数会接收一个参数:dispatch
dispatch函数可以执行异步代码, 有了结果,再分发一个同步的 action
export const increment = (number)=>({type:"increment", number})
export const incrementAsync = number=>{
return dispatch=>{
setTimeout(()=>{
dispatch(increment(number))
}, 1000)
}
}
redux 与 chrome 调试工具
yarn add redux-devtools-extension
combineReducers()
纯函数 ---- 同样的输入,得到同样的输出
不得修改参数 {...state, username: "test"}
不得调动 系统 I/O 的 API
不能调动不纯的 Date.now() 或者 Math.random() 等函数
高阶函数 ---- 参数是函数 或者 返回值是函数
filter、map、addEventListener、
高阶组件 ---- 函数接收一个组件,产生的新组件
connect
前端项目 和 后台服务器项目 各自独立运行
会产生 资源未找到 或者 跨域
- 需要 后台工程师 进行代理服务器配置
- 或者 将 前端项目 和 后台服务器项目 合并
前端项目 置于 后台服务器项目的 public
问题:
BrowserRouter 传递 state ---- 以致于访问 被置为后台路由处理了
解决:
自定义中间件处理
后台没有一个页面能够处理时,查看是否有前台页面可以返回
前台路由路径 不能与 后台路由路径 一样
专门的组件页面 应对 404 和 500 页面
啊
react_结合 redux - 高阶函数 - 高阶组件 - 前端、后台项目打包运行的更多相关文章
- 高阶函数&&高阶组件(二)
高阶组件总共分为两大类 代理方式 操纵prop 访问ref(不推荐) 抽取状态 包装组件 继承方式 操纵生命周期 操纵prop 代理方式之 操纵prop 删除prop import React fro ...
- javascript设计模式学习之三—闭包和高阶函数
一.闭包 闭包某种程度上就是函数的内部函数,可以引用外部函数的局部变量.当外部函数退出后,如果内部函数依旧能被访问到,那么内部函数所引用的外部函数的局部变量就也没有消失,该局部变量的生存周期就被延续. ...
- Python中的高阶函数与匿名函数
Python中的高阶函数与匿名函数 高阶函数 高阶函数就是把函数当做参数传递的一种函数.其与C#中的委托有点相似,个人认为. def add(x,y,f): return f( x)+ f( y) p ...
- Haskell学习-高阶函数
原文地址:Haskell学习-高阶函数 高阶函数(higher-order function)就是指可以操作函数的函数,即函数可以作为参数,也可以作为返回结果.有了这两个特性,haskell可以实现许 ...
- JavaScript中的高阶函数
之前写的<JavaScript学习手册>,客户跟我说有些内容不适合初学者,让我删了,感觉挺可惜的,拿到这里和大家分享. JavaScript中的一切都是对象,这句话同样适用于函数.函数对象 ...
- js 高阶函数 闭包
摘自 https://www.cnblogs.com/bobodeboke/p/5594647.html 建议结合另外一篇关于闭包的文章一起阅读:http://www.cnblogs.com/bob ...
- spark快速开发之scala基础之5高阶函数,偏函数,闭包
高阶函数 高阶函数就是将函数作为参数或者返回值的函数. object function { def main(args: Array[String]): Unit = { println(test(f ...
- 理解运用JS的闭包、高阶函数、柯里化
JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...
- Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊
函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计 ...
随机推荐
- 2018-2019-2 《Java程序设计》第4周学习总结
20175319 2018-2019-2 <Java程序设计>第4周学习总结 教材学习内容总结 第四周学习了如下内容: 子类与父类 子类的继承性 子类与对象 重写方法 super关键字 f ...
- cookie、LocalStorage、sessionStorage三者区别以及使用方式
cookie用来保存客户浏览器请求服务器页面的请求信息 HTML5的WebStorage提供了两种API:localStorage(本地存储)和sessionStorage(会话存储) WebStor ...
- [物理学与PDEs]第4章第2节 反应流体力学方程组 2.3 混合气体状态方程
1. 记号与假设 (1) 已燃气体的化学能为 $0$. (2) 单位质量的未燃气体的化学能为 $g_0>0$. 2. 对多方气体 (理想气体当 $T$ 不高时可近似认为), $$\bex ...
- Jupyter NoteBook功能介绍
一.Jupyter Notebook 介绍 文学编程 在介绍 Jupyter Notebook 之前,让我们先来看一个概念:文学编程 ( Literate programming ),这是由 Dona ...
- JS媒体查询
样式的改变使用C3的媒体查询 行为和功能的改变使用JS的媒体查询 matchMedia()方法参数可写任何一个CSS@media规则,返回的是新的MediaQueryList对象,该对象有两个属性 m ...
- Django-3-Template模板
模板是html文档+Django逻辑语句的组合. 一.变量和标签 变量通过{{ }}来表示,两个大括号中间是变量名. 标签通过{% %}来表示,就是Python中的函数和方法. 常用标签: {% fo ...
- Re-enable extensions not coming from Chrome Web Store on Chrome v35+ (with enhanced security)
1. Add the --enable-easy-off-store-extension-install flag when you start chrome (create shortcut, ed ...
- Kafka简单使用
前言 这几天在写 shell 脚本,学到不少,但是没啥心得之类的,有空可以写个总结(但是大概率不会发表) 现在不算很忙,想再学一点 消息队列相关知识 目前比较出名的也就 RabbitMQ 和 Kafk ...
- SSL双向认证和SSL单向认证的流程和区别
refs: SSL双向认证和SSL单向认证的区别https://www.jianshu.com/p/fb5fe0165ef2 图解 https 单向认证和双向认证!https://cloud.tenc ...
- 一起学爬虫——使用Beautiful Soup爬取网页
要想学好爬虫,必须把基础打扎实,之前发布了两篇文章,分别是使用XPATH和requests爬取网页,今天的文章是学习Beautiful Soup并通过一个例子来实现如何使用Beautiful Soup ...