草庐IT

React生命周期详解

前端开发小陈 2023-04-10 原文

React 类组件生命周期

React 有两个重要阶段 render 阶段和 commit 阶段,React 在调和( render )阶段会深度遍历 React fiber 树,目的就是发现不同( diff ),不同的地方就是接下来需要更新的地方,对于变化的组件,就会执行 render 函数。在一次调和过程完毕之后,就到了commit 阶段,commit 阶段会创建修改真实的 DOM 节点。 react的生命周期可以划分为组件初始化组件更新组件销毁 ,三大阶段分析。

初始化阶段

① constructor 执行

在 mount 阶段,实例化 React 组件,组件中 constructor 就是在这里执行的。 在实例化组件之后,会调用 mountClassInstance 组件初始化。

② getDerivedStateFromProps 执行

在初始化阶段,getDerivedStateFromProps 是第二个执行的生命周期,值得注意的是这是个静态方法,传入 props ,state 。 返回值将和之前的 state 合并,作为新的 state ,传递给组件实例使用。

③ componentWillMount 执行

如果存在 getDerivedStateFromPropsgetSnapshotBeforeUpdate 就不会执行生命周期componentWillMount

④ render 函数执行

⑤componentDidMount执行

执行顺序:constructor -> getDerivedStateFromProps / componentWillMount -> render -> componentDidMount

更新阶段

①执行生命周期 componentWillReceiveProps

首先判断 getDerivedStateFromProps 生命周期是否存在,如果不存在就执行componentWillReceiveProps生命周期。传入该生命周期两个参数,分别是 newProps 和 nextContext 。

②执行生命周期 getDerivedStateFromProps

getDerivedStateFromProps, 返回的值用于合并state,生成新的state。

③执行生命周期 shouldComponentUpdate

shouldComponentUpdate传入新的 props ,新的 state ,和新的 context ,返回值决定是否继续执行 render 函数,调和子节点。这里应该注意一个问题,getDerivedStateFromProps 的返回值可以作为新的 state ,传递给 shouldComponentUpdate 。

④执行生命周期 componentWillUpdate

⑤执行 render 函数

得到最新的 React element 元素。然后继续调和子节点。

⑥执行 getSnapshotBeforeUpdate

生命周期的返回值,将作为第三个参数传递给 componentDidUpdate

⑦执行 componentDidUpdate

此时 DOM 已经修改完成。可以操作修改之后的 DOM 。

更新阶段对应的生命周期的执行顺序: componentWillReceiveProps( props 改变) / getDerivedStateFromProp -> shouldComponentUpdate -> componentWillUpdate -> render -> getSnapshotBeforeUpdate -> componentDidUpdate

销毁阶段

①执行生命周期 componentWillUnmount

在一次调和更新中,如果发现元素被移除,就会调用 componentWillUnmount 生命周期,接下来统一卸载组件以及 DOM 元素。

错误处理

componentDidCatch(err,info)

任何子组件在渲染期间,生命周期方法中或者构造函数 constructor 发生错误时调用。

该方法传入的两个参数:err表示抛出的错误,info表示带有componentStack key的对象,其中包含有关组件引发错误的栈信息。

错误边界不会捕获下面的错误:

  • 事件处理 (Event handlers) (因为事件处理不发生在 React 渲染时,报错不影响渲染)
  • 异步代码 (Asynchronous code) (例如:setTimeout or requestAnimationFrame callbacks)
  • 服务端渲染 (Server side rendering)
  • 错误边界本身(而不是子组件)抛出的错误

static getDerivedStateFromError()

此生命周期会在后代组件抛出错误后被调用,它将抛出的错误作为参数,并返回一个值以更新stategetDerivedStateFromError()会在渲染阶段调用,因此不允许出现副作用,如遇此类情况,请改用componentDidCatch()

React 各阶段生命周期能做些什么

1 constructor

React 在不同时期抛出不同的生命周期钩子,也就意味这这些生命周期钩子的使命。上面讲过 constructor 在类组件创建实例时调用,而且初始化的时候执行一次,所以可以在 constructor 做一些初始化的工作。

constructor(props){
 // 执行 super ,别忘了传递props,才能在接下来的上下文中,获取到props。super(props) this.state={ //① 可以用来初始化state,比如可以用来获取路由中的name:'alien'}this.handleClick = this.handleClick.bind(this) /* ② 绑定 this *//* ③ 绑定防抖函数,防抖 500 毫秒 */this.handleInputChange = debounce(this.handleInputChange , 500) const _render = this.renderthis.render = function(){return _render.bind(this)/* ④ 劫持修改类组件上的一些生命周期 */}
}
/* 点击事件 */
handleClick(){ /* ... */ }
/* 表单输入 */
handleInputChange(){ /* ... */ } 

constructor 作用:

  • 初始化 state ,比如可以用来截取路由中的参数,赋值给 state 。
  • 对类组件的事件做一些处理,比如绑定 this , 节流,防抖等。
  • 对类组件进行一些必要生命周期的劫持,渲染劫持,这个功能更适合反向继承的HOC。

2 getDerivedStateFromProps

getDerivedStateFromProps(nextProps,prevState) 

两个参数:

  • nextProps 父组件新传递的 props ;
  • prevState 组件在此次更新前的 state 。

getDerivedStateFromProps 方法作为类的静态属性方法执行,内部是访问不到 this 的,它更趋向于纯函数,从源码中就能够体会到 React 对该生命周期定义为取缔 componentWillMount 和 componentWillReceiveProps 。

如果把 getDerivedStateFromProps 英文分解 get | Derived | State | From | Props 翻译 得到 派生的 state 从 props 中 ,正如它的名字一样,这个生命周期用于,在初始化和更新阶段,接受父组件的 props 数据, 可以对 props 进行格式化,过滤等操作,返回值将作为新的 state 合并到 state 中,供给视图渲染层消费。

只要组件更新,就会执行 getDerivedStateFromProps,不管是 props 改变,还是 setState ,或是 forceUpdate 。 使用该方法,需要在该方法中返回一个对象或null:如果返回的是对象,则会更新 state,如果返回的是null,则表示不更新。使用该方法的时候需要初始化state,否则在控制台中会出现警告信息,不能在该方法内部,调用this.state

static getDerivedStateFromProps(newProps){const { type } = newProps/* ① 接受 props 变化 , 返回值将作为新的 state ,用于 渲染 或 传递给shouldComponentUpdate */switch(type){case 'fruit' : return { list:['苹果','香蕉','葡萄' ] } case 'vegetables':return { list:['菠菜','西红柿','土豆']}}
}
render(){return <div>{ this.state.list.map((item)=><li key={item} >{ item}</li>) }</div>
} 

getDerivedStateFromProps 作用:

  • 代替 componentWillMount 和 componentWillReceiveProps
  • 组件初始化或者更新时,将 props 映射到 state。
  • 返回值与 state 合并完,可以作为 shouldComponentUpdate 第二个参数 newState ,可以判断是否渲染组件。(请不要把 getDerivedStateFromProps 和 shouldComponentUpdate 强行关联到一起,两者没有必然联系)

3 componentWillMount 和 UNSAFE_componentWillMount

在 React V16.3 componentWillMount ,componentWillReceiveProps , componentWillUpdate 三个生命周期加上了不安全的标识符 UNSAFE,变成了如下形式,在目前最新的版本React V17.0.2 也没有废弃这三个生命周期。可能不久之后更高级的版本会被废除吧,首先先来看一下为什么要加UNSAFE,大家有没有发现一个问题,就是这三个生命周期,都是在 render 之前执行的,React 对于执行 render 函数有着像 shouldUpdate 等条件制约,但是对于执行在 render 之前生命周期没有限制,存在一定隐匿风险,React 开发者滥用这几个生命周期,因为fiber的出现,很可能因为高优先级任务的出现而打断现有任务导致它们会被执行多次

  • UNSAFE_componentWillMount
  • UNSAFE_componentWillReceiveProps
  • UNSAFE_componentWillUpdate

UNSAFE_componentWillMount 的作用还是做一些初始化操作,但是不建议在这个生命周期写,毕竟未来 React 可能完全取缔它。

4 componentWillReceiveProps 和 UNSAFE_componentWillReceiveProps

UNSAFE_componentWillReceiveProps 函数的执行是在更新组件阶段,该生命周期执行驱动是因为父组件更新带来的 props 修改,但是只要父组件触发 render 函数,调用 React.createElement 方法,那么 props 就会被重新创建,生命周期 componentWillReceiveProps 就会执行了。这就解释了即使 props 没变,该生命周期也会执行。

componentWillReceiveProps 可以用来干什么?我把上面例子修改一下。

UNSAFE_componentWillReceiveProps(newProps){const { type } = newProps/*① 监听父组件执行render*/console.log('父组件render执行') /* ② 异步控制props改变,派生出来的 state 的修改*/setTimeout(()=>{switch(type){case 'fruit' : this.setState({list:['苹果','香蕉','葡萄' ] }) breakcase 'vegetables':this.setState({list:['苹果','香蕉','葡萄' ] }) break}},0)
} 
  • componentWillReceiveProps 可以用来监听父组件是否执行 render 。
  • componentWillReceiveProps 可以用来接受 props 改变,组件可以根据props改变,来决定是否更新 state ,因为可以访问到 this , 所以可以在异步成功回调(接口请求数据)改变 state 。这个是 getDerivedStateFromProps 不能实现的。

但是不建议用这种方式,props 改变,再触发 componentWillReceiveProps 异步请求数据渲染,这样首先在没做优化前提下会带来两次子组件的更新,第一次 props 改变,第二次 props 改变,异步改变state 。其次该生命周期的不安全性。再者需要在该生命周期内部,设置大量的条件判断语句,通过 this.props , nextProps 判断 props 到底改变与否。所以完全可以换一种思路,那就是状态提升,把数据层完全托管父组件,子组件没有副作用,只负责渲染父组件传递的 props 即可。

|--------问与答---------|问:当 props 不变的前提下, PureComponent 组件能否阻止 componentWillReceiveProps 执行?

答案是否定的,componentWillReceiveProps 生命周期的执行,和纯组件没有关系,纯组件是在 componentWillReceiveProps 执行之后浅比较 props 是否发生变化。所以 PureComponent 下不会阻止该生命周期的执行。

|--------end---------|

5 componentWillUpdate 和 UNSAFE_componentWillUpdate

UNSAFE_componentWillUpdate 可以意味着在更新之前,此时的 DOM 还没有更新。在这里可以做一些获取 DOM 的操作。就比如说在一次更新中,保存 DOM 之前的信息(记录上一次位置)。但是 React 已经出了新的生命周期 getSnapshotBeforeUpdate 来代替 UNSAFE_componentWillUpdate。

UNSAFE_componentWillUpdate(){/* 获取元素节点 node 位置 */const position = this.getPostion(this.node) 
} 

作用:

  • 获取组件更新之前的状态。比如 DOM 元素位置等。

6 render

还记得在第一节 jsx 主要讲了 render 之后会成什么样子。所谓 render 函数,就是 jsx 的各个元素被 React.createElement 创建成 React element 对象的形式。一次 render 的过程,就是创建 React.element 元素的过程。

  • 那么可以在render里面做一些,createElement创建元素 , cloneElement 克隆元素React.children 遍历 children 的操作。

7 getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps,preState){} 

两个参数:

  • prevProps更新前的props ;
  • preState更新前的state;

把 getSnapshotBeforeUpdate 用英文解释一下 , get | snap shot | before | update , 中文翻译为 获取更新前的快照,可以进一步理解为 获取更新前 DOM 的状态。见名知意,该生命周期是在 commit 阶段的before Mutation ( DOM 修改前),此时 DOM 还没有更新,但是在接下来的 Mutation 阶段会被替换成真实 DOM 。此时是获取 DOM 信息的最佳时期,getSnapshotBeforeUpdate 将返回一个值作为一个snapShot(快照),传递给 componentDidUpdate作为第三个参数。

注意:如果没有返回值会给予警告⚠️,如果没有 componentDidUpdate也会给予警告。所以这个函数必须要配合 componentDidUpdate() 一起使用

getSnapshotBeforeUpdate(prevProps,preState){const style = getComputedStyle(this.node) return { /* 传递更新前的元素位置 */cx:style.cx,cy:style.cy}
}
componentDidUpdate(prevProps, prevState, snapshot){/* 获取元素绘制之前的位置 */console.log(snapshot)
} 

当然这个快照 snapShot 不限于 DOM 的信息,也可以是根据 DOM 计算出来产物。

作用:

  • getSnapshotBeforeUpdate 这个生命周期意义就是配合componentDidUpdate 一起使用,计算形成一个 snapShot 传递给 componentDidUpdate 。保存一次更新前的信息。

8 componentDidUpdate

componentDidUpdate(prevProps, prevState, snapshot){const style = getComputedStyle(this.node)const newPosition = { /* 获取元素最新位置信息 */cx:style.cx,cy:style.cy}
} 

三个参数:

  • prevProps 更新之前的 props ;
  • prevState 更新之前的 state ;
  • snapshot 为 getSnapshotBeforeUpdate 返回的快照,可以是更新前的 DOM 信息。

作用

  • componentDidUpdate 生命周期执行,此时 DOM 已经更新,可以直接获取 DOM 最新状态。这个函数里面如果想要使用 setState ,一定要加以限制,否则会引起无限循环。
  • 接受 getSnapshotBeforeUpdate 保存的快照信息。

9 componentDidMount

componentDidMount 生命周期执行时机和 componentDidUpdate 一样,一个是在初始化,一个是组件更新。此时 DOM 已经创建完,既然 DOM 已经创建挂载,就可以做一些基于 DOM 操作,DOM 事件监听器。

async componentDidMount(){this.node.addEventListener('click',()=>{/* 事件监听 */}) const data = await this.getData() /* 数据请求 */
} 

作用:

  • 可以做一些关于 DOM 操作,比如基于 DOM 的事件监听器。
  • 对于初始化向服务器请求数据,渲染视图,这个生命周期也是蛮合适的。

10 shouldComponentUpdate

shouldComponentUpdate(newProps,newState,nextContext){} 

shouldComponentUpdate 三个参数,第一个参数新的 props ,第二个参数新的 state ,第三个参数新的 context 。

shouldComponentUpdate(newProps,newState){if(newProps.a !== this.props.a ){ /* props中a属性发生变化 渲染组件 */return true}else if(newState.b !== this.props.b ){ /* state 中b属性发生变化 渲染组件 */return true}else{ /* 否则组件不渲染 */return false}
} 
  • 这个生命周期,一般用于性能优化,shouldComponentUpdate 返回值决定是否重新渲染的类组件。需要重点关注的是第二个参数 newState ,如果有 getDerivedStateFromProps 生命周期 ,它的返回值将合并到 newState ,供 shouldComponentUpdate 使用。

11 componentWillUnmount

componentWillUnmount 是组件销毁阶段唯一执行的生命周期,主要做一些收尾工作,比如清除一些可能造成内存泄漏的定时器,延时器,或者是一些事件监听器。

componentWillUnmount(){clearTimeout(this.timer)/* 清除延时器 *//* 卸载事件监听器 */this.node.removeEventListener('click',this.handerClick) 
} 

作用

  • 清除延时器,定时器。
  • 一些基于 DOM 的操作,比如事件监听器。

函数组件生命周期替代方案

useEffect

useEffect 第一个参数 callback, 返回的 destory , destory 作为下一次callback执行之前调用,用于清除上一次 callback 产生的副作用。

第二个参数作为依赖项,是一个数组,可以有多个依赖项,依赖项改变,执行上一次callback 返回的 destory ,和执行新的 effect 第一个参数 callback 。

对于 useEffect 执行, React 处理逻辑是采用异步调用 ,对于每一个 effect 的 callback, React 会向 setTimeout回调函数一样,放入任务队列,等到主线程任务完成,DOM 更新,js 执行完成,视图绘制完毕,才执行。所以 effect 回调函数不会阻塞浏览器绘制视图。

useLayoutEffect:

useLayoutEffect 和 useEffect 不同的地方是采用了同步执行,那么和useEffect有什么区别呢?

  • 首先 useLayoutEffect 是在DOM 绘制之前,这样可以方便修改 DOM ,这样浏览器只会绘制一次,如果修改 DOM 布局放在 useEffect ,那 useEffect 执行是在浏览器绘制视图之后,接下来又改 DOM ,就可能会导致浏览器再次回流和重绘。而且由于两次绘制,视图上可能会造成闪现突兀的效果。
  • useLayoutEffect callback 中代码执行会阻塞浏览器绘制。

一句话概括如何选择 useEffect 和 useLayoutEffect :修改 DOM ,改变布局就用 useLayoutEffect ,其他情况就用 useEffect 。

|--------问与答---------|问:React.useEffect 回调函数 和 componentDidMount / componentDidUpdate 执行时机有什么区别 ?

答:useEffect 对 React 执行栈来看是异步执行的,而 componentDidMount / componentDidUpdate 是同步执行的,useEffect代码不会阻塞浏览器绘制。在时机上 ,componentDidMount / componentDidUpdate 和 useLayoutEffect 更类似。

|---------end----------|

上述详细的介绍了 useEffect 和 useLayoutEffect,接下来拿 useEffect 做参考,详细介绍一下函数组件怎么实现生命周期的替代方案的。

componentDidMount 替代方案

React.useEffect(()=>{/* 请求数据 , 事件监听 , 操纵dom */
},[])/* 切记 dep = [] */ 

这里要记住 dep = [] ,这样当前 effect 没有任何依赖项,也就只有初始化执行一次。

componentWillUnmount 替代方案

 React.useEffect(()=>{/* 请求数据 , 事件监听 , 操纵dom , 增加定时器,延时器 */return function componentWillUnmount(){/* 解除事件监听器 ,清除定时器,延时器 */}
},[])/* 切记 dep = [] */ 

在 componentDidMount 的前提下,useEffect 第一个函数的返回函数,可以作为 componentWillUnmount 使用。

componentWillReceiveProps 代替方案

说 useEffect 代替 componentWillReceiveProps 着实有点牵强。

  • 首先因为二者的执行阶段根本不同,一个是在render阶段,一个是在commit阶段。
  • 其次 useEffect 会初始化执行一次,但是 componentWillReceiveProps 只有组件更新 props 变化的时候才会执行。
React.useEffect(()=>{console.log('props变化:componentWillReceiveProps')
},[ props ]) 

此时依赖项就是 props,props 变化,执行此时的 useEffect 钩子。

React.useEffect(()=>{console.log('props中number变化:componentWillReceiveProps')
},[ props.number ]) /* 当前仅当 props中number变化,执行当前effect钩子 */ 

useEffect 还可以针对 props 的某一个属性进行追踪。此时的依赖项为 props 的追踪属性。如上述代码,只有 props 中 number 变化,执行 effect 。

componentDidUpdate 替代方案

useEffect 和 componentDidUpdate 在执行时期虽然有点差别,useEffect 是异步执行,componentDidUpdate 是同步执行 ,但都是在 commit 阶段 。但是向上面所说 useEffect 会默认执行一次,而 componentDidUpdate 只有在组件更新完成后执行。

React.useEffect(()=>{console.log('组件更新完成:componentDidUpdate ') 
}) /* 没有 dep 依赖项 */ 

注意此时useEffect没有第二个参数。

没有第二个参数,那么每一次执行函数组件,都会执行该 effect。

生命周期相关问题

为什么要改变生命周期

被废弃的三个函数都是在render之前,因为fiber的出现,很可能因为高优先级任务的出现而打断现有任务导致它们会被执行多次,这肯定不是你想要的结果。

另外的一个原因则是,React想约束使用者,好的框架能够让人不得已写出容易维护和扩展的代码,所以需要使用新的生命周期函数。

为什么数据获取要在componentDidMount中进行

首先,分析一下两者请求数据的区别:

componentWillMount获取数据:

1.执行willMount函数,等待数据返回
2.执行render函数
3.执行didMount函数
4.数据返回, 执行render

didMount获取数据:

1.执行willMount函数
2.执行render函数
3.执行didMount函数, 等待数据返回
4.数据返回, 执行render

很明显,在willMount中获取数据,可以节省时间(render函数和didMount函数的执行时间),但是为什么我们还要在didMount中获取数据

1.如果使用服务端渲染的话,willMount会在服务端和客户端各自执行一次,这会导致请求两次(接受不了~),而didMount只会在客户端进行
2.在Fiber之后, 由于任务可中断,willMount可能会被执行多次
3.willMount会被废弃,目前被标记为不安全
4.节省的时间非常少,跟其他的延迟情况相比,这个优化可以使用九牛一毛的形容(为了这么一点时间而一直不跟进技术的发展,得不偿失),并且render函数是肯定比异步数据到达先执行,白屏时间并不能减少

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

有关React生命周期详解的更多相关文章

  1. ruby-on-rails - Ruby 长时间运行的进程对队列事件使用react - 2

    我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby​​脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几

  2. 物联网MQTT协议详解 - 2

    一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su

  3. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  4. ruby - 单个 EventMachine react 器中的多个服务器 - 2

    是否可以在单个事件机器中运行多个服务器?我的意思是,多个服务可以由一个客户端连接同时使用。例如,登录服务器对用户进行身份验证,然后用户可以同时使用聊天室和简单的游戏,例如带有单个客户端套接字的跳棋?或者我是否需要为每个服务使用多个事件机器react器? 最佳答案 我试过了,它正在工作:#!/usr/bin/envrubyrequire'eventmachine'moduleEchoServerdefpost_initputs"--someoneconnectedtotheechoserver!"enddefreceive_datad

  5. 【详解】Docker安装Elasticsearch7.16.1集群 - 2

    开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建

  6. 【Elasticsearch基础】Elasticsearch索引、文档以及映射操作详解 - 2

    文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就

  7. 最强Http缓存策略之强缓存和协商缓存的详解与应用实例 - 2

    HTTP缓存是指浏览器或者代理服务器将已经请求过的资源保存到本地,以便下次请求时能够直接从缓存中获取资源,从而减少网络请求次数,提高网页的加载速度和用户体验。缓存分为强缓存和协商缓存两种模式。一.强缓存强缓存是指浏览器直接从本地缓存中获取资源,而不需要向web服务器发出网络请求。这是因为浏览器在第一次请求资源时,服务器会在响应头中添加相关缓存的响应头,以表明该资源的缓存策略。常见的强缓存响应头如下所述:Cache-ControlCache-Control响应头是用于控制强制缓存和协商缓存的缓存策略。该响应头中的指令如下:max-age:指定该资源在本地缓存的最长有效时间,以秒为单位。例如:Ca

  8. IDEA 2022 创建 Spring Boot 项目详解 - 2

    如何用IDEA2022创建并初始化一个SpringBoot项目?目录如何用IDEA2022创建并初始化一个SpringBoot项目?0. 环境说明1.  创建SpringBoot项目 2.编写初始化代码0. 环境说明IDEA2022.3.1JDK1.8SpringBoot1.  创建SpringBoot项目        打开IDEA,选择NewProject创建项目。        填写项目名称、项目构建方式、jdk版本,按需要修改项目文件路径等信息。        选择springboot版本以及需要的包,此处只选择了springweb。        此处需特别注意,若你使用的是jdk1

  9. 详解Unity中的粒子系统Particle System (二) - 2

    前言上一篇我们简要讲述了粒子系统是什么,如何添加,以及基本模块的介绍,以及对于曲线和颜色编辑器的讲解。从本篇开始,我们将按照模块结构讲解下去,本篇主要讲粒子系统的主模块,该模块主要是控制粒子的初始状态和全局属性的,以下是关于该模块的介绍,请大家指正。目录前言本系列提要一、粒子系统主模块1.阅读前注意事项2.参考图3.参数讲解DurationLoopingPrewarmStartDelayStartLifetimeStartSpeed3DStartSizeStartSize3DStartRotationStartRotationFlipRotationStartColorGravityModif

  10. VMware虚拟机与本地主机进行磁盘共享(详解) - 2

    VMware虚拟机与本地主机进行磁盘共享前提虚拟机版本为Windows10(专业版,不是可能有问题)本地主机为家庭版或学生版(此版本会有问题,但有替代方式)最好是专业版VMware操作1.关闭防火墙,全部关闭。2.打开电脑属性3.点击共享-》高级共享-》权限4.如果没有everyone,就添加权限选择完全控制,然后应用确定。5.打开cmd输入lusrmgr.msc(只有专业版可以打开)如果不是专业版,可以跳过这一步。点击用户-》administrator密码要复杂密码,否则不行。推荐admaiN@1234类型的密码。设置完密码,点击属性,将禁用解开。6.如果虚拟机的windows不是专业版,可

随机推荐