React 默认不是双向绑定的,它不监听数据对象,而是通过手动调用 setState() 方法来触发了 Virtual DOM 的更新,再用 diff 算法来进行 Virtual DOM 比较前后两个状态的不同,看看是哪个 DOM 节点更新了,然后针对性的更改变化了的 DOM 结构实现数据更新,渲染 Actual DOM
function FuncWrapper(func) {
return function () {
console.log('before')
func()
console.log('after')
}
}
var first = FuncWrapper(first)
var second = FuncWrapper(second)
前阵子在部门内做了一个关于
React
的分享,为了更进一步地理解,也分享给有需要的小伙伴,做了如下整理 ^_^Facebook 在 2013 年 5 月推出了全新的函数式编程,也就是全球范围内使用人数最多的前端框架 -
React
,也是目前最受欢迎的前端框架之一现代框架与旧式框架的区别
React
是一个视图层框架,是用来解决数据和页面渲染的问题同样的还要
Vue
和Angular
,这也是目前前端最受欢迎的三套框架,几乎是所有前端工程师必备的一项技能所以我们在技术选型的时候,常常会产生困扰,究竟应该选择哪一门语言开发项目呢,比如
reactjs
: 灵活性更大,处理大型业务时选择性更多一点vuejs
: api更多,实现功能更简单,但也因为api多,灵活性有一定限制所以,在做复杂度比较高的项目时,大家倾向于
reactjs
,而面向用户端的一些复杂度不是特别高的项目时,用vuejs
更简单当然,
vuejs
也可以做大型的项目,至于具体选什么框架,还需要取决于对框架的熟悉程度以及业务复杂度做一个权衡而在几年前开发前端应用时,基本没这个困扰,因为大家开发都用
jQuery
但随着前端交互的复杂度越来越高,现代框架比如
react
、vue
逐渐的替换掉了jQuery
,因为用现代框架来开发更容易维护为什么会说变得容易维护呢?我们先来看看
react
和jQuery
到底什么区别我认为,他们之间编程思想的最大区别,就是声明式与命令式的区别
命令式
命令式编程,比如
jQuery
,直接操作DOM
,告诉页面怎么挂载,怎么操作,整个程序有 70% 都是操作DOM
例如上面的代码,点击一个按钮,切换 button 颜色。我们用
jQuery
这种命令式编程思路写,就是当前是什么颜色就让它变成另外一个颜色但如果我们认真想想,其实这里面可以细分成两个行为,一个是对状态判断,另一个是操作
DOM
。那声明式呢?声明式
还是上面那个场景,我们用
React
提供的 JSX 语法来实现,当我们用 JSX 描述了映射关系之后,点击按钮事件时,只需要对颜色这个变量进行修改就可以完成需求了所以区别就出来了,用
react
来实现同样的需求,如果细分来看,我们在逻辑上只有状态这一个行为而
jQuery
是两个行为,状态 + DOM 操作那为什么
React
要用声明式来编程呢?因为命令式编程是直接操作
DOM
节点,如果有多个事件,比如 100 个 button 上都有点击和取消事件,那频繁的事件操作会很大程度上产生 bug ,而且不可控,会有无法预期性的 bug 产生而且声名式编程只需要我们操作数据就好,数据可能出现的几种情况我们能提前做好容错
声明式是通过描述状态与视图之间的映射关系来操作DOM,或者说具体点是用这样的映射关系来生成一个
DOM
节点插入到页面去比如
React
提供的 JSX 和Vue
中的模板语言目的是为了实现声明式渲染的功能,本质上都是描述了 『状态』与『视图』之间的映射关系
状态与视图之间的映射关系,等同于
render
函数在框架的内部,不论是 JSX 还是
Vue
的模板,最终会编译成render
函数。声明式渲染是现代框架的特性,也就是我们常说的数据驱动视图
这个特性跟声明式可以简化维护应用代码的复杂度有什么关系呢?
事实上,这个特性可以让我们把关注点只放在状态的维护上。这样一来,即使应用复杂后,我们管理代码的方式只在状态上,所有的视图操作都不用关心了,因为框架会帮我们自动去做,可以说大大降低代码维护的成本
状态
那我们所说的这个状态到底是什么呢?
在 React 官网上,我们可以看到其介绍是用于构建用户界面的
JavaScript
库,所以React
本质上是一个创建 UI 接口的视图层框架前面我们已经提到了
React
有个声明式思想,它是数据到视图的一个静态映射,但在我们的实际项目中,并不是一个静态网页,还需要操作数据,网页的状态可能随时改变,那怎么才能让网页跟着状态一起改变呢?响应式设计思想
这就是
React
背后的响应式设计思想开发者只需要告诉
React
我们希望页面长什么样子,React
就会自动帮我们绘制界面也就是说,我们只要操作数据,页面视图会自动作出响应,用户界面的展示完全取决于数据层
而且我们一切的操作都是基于内存之中,不会有较大的性能损耗,这就是
React
响应式编程的精髓,也是为何它叫作React
,React
在英文中是响应的意思简单来说就是,不需要关注视图层,只需要关注数据层的变化
一个类
class
一定有一个构造函数constructor
,最优先被执行constructor
接收props
参数,super
指的是父类Component
,super(props)
方法指的是调用父类的构造函数定义数据需要定义在状态里面
this.state
框架是怎么知道 Web 应用在运行时数据状态发生了变化呢? 这个问题是所有框架必须去解决的
不同的解决方案,导致的直接结果就是它所提供给用户的上层语法或 API 完全不一样,也是我们常对比的各个框架的使用区别
解决方案包括我们常说的
Virtual DOM
、diff
算法对比对
Virtual DOM
有兴趣的小伙伴可以查看我的另一篇博客Virtual DOM
中那些你不知道的事,在这篇博客里有对Virtual DOM
做一个详细的讲解服务端渲染
既然提到了
Virtual DOM
,这里就提一下React
的价值 -nodejs
服务端渲染因为有
Virtual DOM
的存在,React
可以很容易的将Virtual DOM
转换为字符串,这便使我们可以只写一份 UI 代码,同时运行在 node 里和和浏览器里在 node 里将组件 HTML 渲染为一段 HTML 一句话即可,不过围绕
renderToString
还需要做一些准备工作整个思路大致是:
React
组件React.renderToString()
方法来生成 HTML这就是
React
的服务端渲染,组件的代码前后端都可以复用不仅如此,
React
还能够用一套代码同时运行在浏览器和 node 里,而且能够以原生 App 的姿势运行在 iOS 和 Android 系统中,即拥有了 web 迭代迅速的特性,又拥有原生 App 的体验,也就是React-Native
单向数据流
我认为使用
react
的最大好处在于功能组件化,遵守前端可维护的原则react
是单向数据流,什么是单向数据流呢?数据主要从父节点传递到子节点( 通过
props
),即遵循从上到下的数据流向如果顶层( 父级 )的某个
props
改变了,react
会重渲染所有的子节点通俗的理解是指用户访问
View
,View
发出用户交互的Action
,在Action
里对state
进行相应更新。state
更新后会触发View
更新页面的过程。这样数据总是清晰的单向进行流动,便于维护并且可以预测那为什么
react
要使用单向数据流呢?实际上,单向数据流这种模式十分适合跟
react
搭配使用它的主要思想是组件不会改变接收的数据。它们只会监听数据的变化,当数据发生变化时它们会使用接收到的新值,而不是去修改已有的值。当组件的更新机制触发后,它们只是使用新值进行重新渲染而已
它消除了在多个地方同时管理状态,可能出现的数据不同步的情况,它只会在一个地方进行状态管理,减小了应用的复杂度,唯一的数据源将使得开发更加简单
对于
react
来说,单向数据流( 从上到下 )与单一数据源这两个原则,限定了react
中要想在一个组件中更新另一个组件的状态(类似于vue
的平行组件传参,或者是子组件向父组件传递参数),需要进行状态提升即将状态提升到他们最近的祖先组件中。子组件中
Change
了状态,触发父组件状态的变更,父组件状态的变更,影响到了另一个组件的显示(因为传递给另一个组件的状态变化了,这一点与vue
子组件的$emit()
方法很相似)比如在做 list 删除时,为什么不可以直接把 list 传给子组件来改变 list?
因为父组件可以向子组件传值,但是子组件只能去使用这个值,不能去改变这个值
应该是父组件向子组件传递方法,子组件调用这个方法,传递一个数据,最终还是父组件自己来改变这个数据
Vue也是单向数据流,只不过能实现双向绑定,UI 控件提供了双向数据绑定的方式,在一些需要实时反应用户输入的场合会非常方便
但通常认为复杂应用中这种便利比不上引入状态管理带来的优势
所以无论是
vue
还是react
其实还是提倡单向数据流去管理状态,这一点在vuex
和redux
状态管理器上体现的很明显虽然
vue
和react
框架本身有自己状态管理,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏所以就需要
vuex
和redux
来解决这个问题,redux
在我的另一篇博客大白话解析 Redux 、 redux-thunk 、redux-saga 和 react-redux 中介绍的很详细了,大家有兴趣可以去看看单向数据流中的单向,指的是数据从父组件到子组件的这个流向叫单向
绑定的单双向是指View层与Module层之间的映射关系
但我们通常也说双向数据绑定,带来双向数据流
数据(
state
)和视图(View
)之间的双向绑定,ng 里的 ng-model 和 vue 里的 v-modelprops
刚才我们提到了
props
,怎么理解props
呢?props
是property
的缩写,可以理解为 HTML 标签的attribute
在组件内部,可以通过 this.props 来访问 props,props 是组件唯一的数据来源
不可以使用
this.props
直接修改 props,因为 props 是只读的,props 是用于整个组件树中传递数据和配置PropTypes 与 DefaultProps
react 为我们提供了一套非常简单好用的属性校验机制,强校验:
PropTypes
包含的校验类型包括基本类型、数组、对象、实例、枚举state
React
的一大创新,就是把每一个组件都看成是一个状态机,组件内部通过 state 来维护组件状态的变化,这也是state 唯一的作用每个组件都有属于自己的
state
,state 和 props 的区别在于前者 ( state ) 只存在于组件内部,只能从当前组件调用this.setState
修改state
值( 不可以直接修改this.state
)一般我们更新子组件都是通过改变
state
值,更新子组件的props
值从而达到更新state
一般和事件一起使用,比如有一个简单的开关组件,开关状态会以文字的形式表现在按钮的文本上首先需要在
render
方法中返回了一个 button 元素,给 button 注册了一个事件用来处理点击事件,在点击事件中对state
的描述开关状态的字段,比如 on 取反,并执行this.setState()
方法设置 on 字段的新值。一个开关组件就完成了react
通过将事件处理器绑定到组件上来处理事件react
事件本质上和原生 JS 一样,鼠标事件用来处理点击操作,表单事件用于表单元素变化等,react
事件的命名、行为和原生 JS 差不多,不一样的地方是react
事件名区分大小写事件的处理器需要由组件的使用者来提供,可以通过
props
将事件处理器传进来这是一个
react
组件实现组件可交互所需的流程,render()
输出Virtual DOM
,Virtual DOM
转为 DOM,再在 DOM 上注册事件,事件触发setState()
修改数据,在每次调用setState
方法时,react
会自动执行render
方法来更新Virtual DOM
,如果组件已经被渲染,那么还会更新到 DOM 中去setState 方法
新版的
setState
可以接收一个函数而不是一个对象了,需要有一个返回值 return 所以我们可以在项目中做一些优化,比如可以优化为
可以用
prevState
,改为而
可以改为
props 与 state
尽可能使用
props
当做数据源,state
用来存放状态值( 简单的数据 )也就是说咱们通常用
props
传递大量数据,state
用于存放组件内部一些简单的定义数据当组件的
state
或者props
发生改变的时候,render
函数就会重新执行当父组件的
render
函数被运行时,它的子组件的render
都将重新被运行一次单向数据流和单向数据绑定是什么区别呢
前面已经提到了单向数据流,需要按照它的顺序办事。比如我们假设有一个这样的生命周期:
改了一个数,view 层不能反回头来找他来更新 view 层视图( 从步骤 2 跳回去 1 ),你得等下一个循环(转了一圈)的步骤 1 才能更新视图。react 就是这样子,你得
setState
触发更新,如果你this.state = {...}
,是没用的,它一直不变单向数据绑定,就是绑定事件,比如绑定
onInput
、onChange
、storage
这些事件,只要触发事件,立刻执行对应的函数(代表 react)双向数据绑定,我们一般是借用 js 底层的
Object.defineproperty
( 代表Vue
)这是
Vue
双绑的核心思想,view
层能让model
层变了,model
层也能让view
层变了要判断是单向绑定还是双向绑定,只需要手动去控制台改一下那个核心绑定的数据,view 层的显示内容能马上变化的就是双绑,不能马上有变化的只是单向数据
想做到像
Vue
那样的极致双绑,能够在控制台改个数据就改变视图的,大概就只有defineproperty
(据说新版vue
现在用ES6
的proxy
)和定时器轮询了既然说到了数据流,那组件间是怎么进行通信的呢?
组件通信
一般来说,有两种通信方式
父子组件通信
在
react
中,最为常见的组件通信也就是父子了,一般情况是:父组件更新组件状态 -----props-----> 子组件更新
另一种情况是
子组件更新父组件状态 -----需要父组件传递回调函数-----> 子组件调用触发
可能大家对于第二种子组件更新父组件状态的情况有些不理解
一般情况下,只能由父组件通过
props
传递数据给子组件,使得子组件得到更新那么现在,我们想实现子组件更新父组件,就需要父组件通过 props 传递一个回调函数到子组件中,这个回调函数可以更新父组件,子组件就是通过触发这个回调函数,从而使父组件得到更新
兄弟组件通信
当两个组件处于同一级时( 同处父级,或者同处子级 ),就称为兄弟组件
这里也有两种实现方式
方式一
按照React单向数据流方式,我们需要借助父组件进行传递,通过父组件回调函数改变兄弟组件的props
其实这种实现方式与子组件更新父组件状态的方式是大同小异的
方式一只适用于组件层次很少的情况,当组件层次很深的时候,整个沟通的效率就会变得很低
方式二
React官方给我们提供了一种上下文方式,可以让子组件直接访问祖先的数据或函数,无需从祖先组件一层层地传递数据到子组件中
但这种方法建议按需使用,可能会导致一些不可预期的错误。( 比如数据传递逻辑结构不清晰 )
组件划分
前面已经提到使用
react
的最大好处在于功能组件化,遵守前端可维护的原则事实上,
react
组件化开发原则是组件负责渲染 UI,组件的不同状态对应着不同 UI,通常遵循以下组件设计思路布局组件:仅仅涉及应用 UI 界面结构的组件,不涉及任何业务逻辑,数据请求及操作
容器组件:负责获取数据,处理业务逻辑,通常在
render()
函数内返回展示型组件展示型组件:负责应用的界面 UI 展示
UI 组件:指抽象出的可重用的 UI 独立组件,通常是无状态组件
实际项目中,最好将 UI 组件和容器组件拆分, UI 组件负责页面渲染,容器组件负责页面逻辑
当组件中只有一个 render 函数时,就可以定义成无状态组件
无状态组件的性能比较高,因为它就是一个函数,而 React 里边普通的组件是 JS 里边的一个类,这个类生成的对象里,还会有一些生命周期函数,所以它执行起来,既要执行生命周期函数,又要执行 render ,它要执行的东西远比函数执行的东西多的多,所以一个普通组件的性能是肯定赶不上无状态组件的
生命周期函数
React的组件拥有一套清晰完整而且非常容易理解的生命周期机制
大体可以分为三个过程:初始化、更新和销毁
在组件生命周期中,随着组件的
props
或者state
发生改变,它的Virtual DOM
和DOM
表现也将有相应的变化什么叫生命周期函数?生命周期函数指在某一时刻组件会自动调用执行的函数
在子组件中
Mount
是指组件被挂载执行的过程,Updation
是指组件被更新执行的过程,什么情况发生更新呢?要么是state
被更新,要么是props
被更新,也就是数据发生变化的时候,页面会更新它的底层为什么会有这样的设定呢?原因就是组件是继承自
Component
这个组件的,React Component
这个组件里边默认内置了其他所有的生命周期函数,唯独没有内置render
函数,所以对组件来说,render
是必须自己定义的,不然就会报错React 生命周期函数的使用场景
上面讲了
React
的生命周期函数,有一个比较容易忽视的钩子函数shouldComponentUpdate
,他的使用过程是怎样的呢?我们先来做个测试,看下子组件的渲染过程,先把所有的生命周期函数都删除掉,只在子组件的
render
函数中留下console.log('child render')
然后我们在 input 框中输入内容,在控制台可以看到这样的结果
也就是父组件
render
函数重新执行的时候,子组件的render
函数也会跟着执行这样的逻辑是没有问题的,但是它会带来性能上的损耗
父组件上的内容发生变化了,其实子组件的内容是没必要重新渲染的,而这样的机制会导致子组件要做很多无谓的渲染
那应该怎样做性能优化呢?
很简单,这个时候我们就可以利用生命周期函数
shouldComponentUpdate
来做性能优化了shouldComponentUpdate
这个函数的意思是,当数据或者内容发生变化的时候,会先询问一下,组件是否要被真正的更新shouldComponentUpdate
一般会接收两个参数,一个是nextProps
,另一个是nextState
当一个组件要被更新的时候,
props
要被更新成什么样呢?nextProps
指的是接下来props
要被变化成什么样,nextState
指的是接下来state
要被变化成什么样我们的组件
props
接收的 content ,如果 content 发生变化,这个组件才需要重新渲染,没有发生变化时,不需要发生渲染这样就通过
shouldComponentUpdate
这个生命周期函数提升了组件的性能,可以避免一个组件做无谓的render
操作render
函数重新执行,就意味着React
底层要生成一份Virtual DOM
,和之前的Virtual DOM
做比对,虽然Virtual DOM
的比对比Actual DOM
的比对要快的多,但是,如果能省略这个比对过程当然能节约更多的性能性能优化
当然,
React
当中有很多关于性能优化的点首先是
this.handleClick.bind(this)
这样的方法,如果要改变作用域的话,我们把作用域的修改放在constructor
里边,这样可以保证整个程序里边这个函数的作用域绑定只会执行一次,而且可以避免组件的一些无谓渲染,所以,这样写代码,react
组件的性能会有所提升其次,
react
的底层setState
内置了性能提升的机制,是一个异步的函数,可以把多次数据的改变结合成一次来做,这样可以降低Virtual DOM
的比对频率再者
react
的底层使用了Virtual DOM
的概念,还有同层比对,还有key
的概念,来提升Virtual DOM
比对的速率,从而提升react
的性能最后,也就是借助
shouldComponentUpdate
这个方法,可以提高react
组件的性能,因为我们可以避免无谓的组件的render
函数的运行监听数据对象
由于之前用过一段时间的
Vue
,在转到React
开发的时候,可以明显的发现React
并没有Vue
可以watch
数据对象的方法那
React
是怎么检测数据对象的变化呢?React
默认不是双向绑定的,它不监听数据对象,而是通过手动调用setState()
方法来触发了Virtual DOM
的更新,再用diff
算法来进行Virtual DOM
比较前后两个状态的不同,看看是哪个 DOM 节点更新了,然后针对性的更改变化了的 DOM 结构实现数据更新,渲染Actual DOM
我们单纯的使用
React
,状态发生变化,会触发组件生命周期中的如下方法:但如果结合
Redux
使用,一般状态变化是由Dispatch
引起的,我们可以在Dispatch
的回调中执行相应的操作函数式编程
react
把需要不断重复构建的 UI 抽象成了组件,它充分利用很多函数式的方法减少了冗余代码可以说,函数式编程是 React 的精髓
那到底什么是函数式编程呢?
比起命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程。
也就是说,函数式编程和命令式编程最大的区别是:
函数式编程关心数据的映射,而命令式编程关心解决问题的步骤
而且维护方便,面向测试的开发流程
一个高阶函数,它可以接收函数可以当参数,也可以当返回值,这就是函数式编程
像柯里化、装饰器模式、高阶组件,都是相通的,一个道理
举个简单的 🌰
现在想在每条
console
语句前后各加一条console
语句,如果在每个函数都加上console
语句,会产生不必要的耦合,所以高阶函数就派上了用场我们写了一个函数
FuncWrapper
,该函数接一个函数作为参数,将参数函数装饰了一层,返回出去,减少了代码耦合在设计模式中称这种模式为装饰器或装饰者模式
在
React
中,高阶组件HOC
就相当于这么一个FuncWrapper
,传入一个组件,返回被包装或者被处理的另一个组件高阶组件
高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件
高阶组件就是一个没有副作用的纯函数
本质上是一个类工厂,先举个简单的 🌰
组件一:
组件二:
有两个不相同的组件,但是有部分功能重合,比如
h2
标题的内容,changeHandle
函数,这样也就造成了代码的冗余理解了高阶函数,再解决这类问题就不难了吧?接下来我们加入高阶组件解决这个问题
高阶组件:
在高阶组件返回包装好的组件的时,我们将高阶组件的
props
展开并传入包装好的组件中,这是确保给高阶组件的props
也能给到被包装的组件上简化接下来的两个组件
组件一:
组件二:
高阶组件的用途很多,比如代码复用,逻辑抽象,抽离底层代码,渲染劫持,更改
state
、更改props
等等包括我们经常用到的
react-redux
的connect
函数把
redux
的state
和action
创建函数,通过props
注入给了Component
你在目标组件
Component
里面可以直接用this.props
去调用redux state
和action
创建函数了相当于
antd
的Form
组件也是一样的上述高阶组件中我们用了 ES6 装饰器语法,
@HocUITest('lisi')
就是一个装饰器,它修改了类的行为也就是说,装饰器是一个对类进行处理的函数
需要注意的是,装饰器对类的行为的改变,是代码编译时发生的,而不是在运行时
这意味着,装饰器能在编译阶段运行代码
也就是说,装饰器本质就是编译时执行的函数
为了传递更多的参数,上面的装饰器函数外面又封装了一层函数
比如,我们实际开发时,
React
与Redux
库结合使用时,常常需要写成下面这样有了装饰器,就可以改写上面的代码
接下来我们主要说一下两种功能的
react
高阶组件:属性代理、反向继承属性代理
高阶组件将它收到的
props
传递给被包装的组件,所叫属性代理主要用来处理以下问题
props
state
refs
获取组件实例反向继承
为什么叫反向继承,是高阶组件继承被包装组件,按照我们想的被包装组件继承高阶组件
反向代理主要用来做渲染劫持
所谓的渲染劫持,就是最后组件所渲染出来的东西或者我们叫
React Element
完全由高阶组件来决定,通过我们可以对任意一个React Element
的props
进行操作;我们也可以操作React Element
的Child
用过
React-Redux
的人可能会有印象,使用connect
可以将react
和redux
关联起来,这里的connect
就是一个高阶组件ref 的使用
ref
是reference
的简写,它是一个引用,在React
,可以使用ref
操作 DOM在
React 16
的新语法中,ref
应该等于一个函数(箭头函数)ref={(input) => {this.input = input}}
,构造了一个ref
引用,这个引用叫this.input
,它指向input
对应的 DOM 节点。所以this.input
指向的就是input
框的 DOM所以下面的方法
可以改为
应该尽量保持少操作 DOM ,
setState
是异步函数,操作 DOM 时必须写到回调中比如
ref
是帮助我们在React
中直接获取 DOM 元素的时候使用的,一般情况下尽量避免使用ref
,但是有的时候一些极其复杂的业务,比如动画的时候,不可避免的还是要用到 DOM 标签,怎么用呢,就用ref
来获取 DOM 标签补充知识
开发环境搭建
快速搭建
React
的开发环境有两种方法通过 CDN 引入 .js 文件来使用
React
使用
create-react-app
脚手架工具来编码在脚手架的代码并不能直接运行,需要脚手架进行编译,编译出来的代码才可以被浏览器识别运行,一般会使用
webpack
、gulp
这样的工具工程目录简介
yarn.lock
- 项目依赖的安装包package.json
- node 的包文件,包含项目的介绍、项目依赖的包、指令供调用,让项目变成node的包public favicon.ico
- 项目左上角图标,index.html
模板src index.js
- 整个程序运行的入口文件注意事项
state
不允许做任何改变,可以先拷贝state
中的值const list = [...this.state.list]
转义的情况下,比如输入:
<h1>hello</h1>
会显示<h1>hello</h1>
不转义的情况下,比如输入:
<h1>hello</h1>
会显示hello
:在
React
中使用表单时,label
元素的for
标签要替换成htmlFor
使用 Charles 实现本地数据 mock
在前端开发代码的时候实际上和后端是分离的,也就需要在本地进行接口数据的模拟,这个时候就需要使用 Charles 进行接口数据的模拟
具体操作我在博客大白话解析 Redux 、 redux-thunk 、redux-saga 和 react-redux里边已经讲到了,有兴趣的小伙伴可以去看看
我们先
npm install axios --save
安装axios
然后在程序中引入
axios
:import axios from 'axios'
Charles
这个工具的原理是什么?它可以抓到浏览器向外发送的请求,然后对一些请求做一些处理,比如说,抓取到请求的是
http://localhost:3000/list.json
他有一个规则是,只要你请求的下面这个地址
就会把
Local path
这个本地文件的内容返回给你所以
Charles
其实就是一个中间的代理服务器,可以抓取到浏览器的请求,如果有些接口是需要模拟的话,就可以使用Charles
的Map Local
这个功能去模拟数据当然,用脚手架的话,我们也可以在 public 文件夹中 mock 请求
结尾
这篇文章主要从编程思想入手剖析
React
,包括如何快速构建组件和应用,让你快速了解React
的编程原理当然,对于构建大型应用,我们还需要结合 Redux 、 react-router 和 axios,大家有兴趣的话,都可以瞧瞧 ^_^