[轉(zhuǎn)]深入淺出 React -- 生命周期

[轉(zhuǎn)]深入淺出 React -- 生命周期
這里通過對(duì) React15 和 React16 兩個(gè)版本的生命周期進(jìn)行對(duì)比總結(jié),來建立系統(tǒng)而完善的生命周期知識(shí)體系.

生命周期背后的設(shè)計(jì)思想

React 設(shè)計(jì)的兩個(gè)核心概念:“組件” 和 “虛擬 DOM”

虛擬 DOM

當(dāng)組件初始化時(shí),通過調(diào)用生命周期中的 render 方法经窖,生成虛擬 DOM靠娱;再通過調(diào)用 ReactDOM.render 方法人芽,將虛擬 DOM 轉(zhuǎn)換為真實(shí) DOM索烹。

當(dāng)組件更新時(shí),會(huì)再次調(diào)用生命周期中的 render 方法岸啡,生成新的虛擬 DOM蛇捌;然后通過 diff 算法定位兩次虛擬 DOM 的差異抚恒,對(duì)發(fā)生變化的真實(shí) DOM 做定向更新。

組件化

在一個(gè) React 項(xiàng)目中络拌,幾乎所有的內(nèi)容都可以抽離為各種各樣的組件俭驮,每個(gè)組件既是 “封閉” 的,也是 “開放” 的春贸。

所謂 “封閉”混萝,是針對(duì)組件數(shù)據(jù)改變到組件實(shí)際發(fā)生更新的過程。在組件自身的渲染過程中萍恕,每個(gè)組件都只會(huì)處理它自身內(nèi)部的渲染邏輯逸嘀。在沒有數(shù)據(jù)交流的情況下,組件之間互不干擾允粤。

所謂 “開放”崭倘,是針對(duì)組件間通信的。React 允許開發(fā)者基于單向數(shù)據(jù)流的原則來完成組件之間的通信类垫。組件之間的通信可能使通信組件的渲染結(jié)果產(chǎn)生影響司光。所以說組件之間是相互開放的,可以相互影響的悉患。

React 組件的 “開放” 與 “封閉” 特性残家,使得 React 的組件具備高可重用性和可維護(hù)性。

生命周期方法

生命周期的 render 方法將虛擬 DOM組件兩者結(jié)合到了一起售躁。

虛擬 DOM 的生成依賴 render跪削,而組件的渲染過程也離不開 render谴仙。所以可以將 render 方法比作組件的“靈魂”迂求。

render 之外的生命周期方法可以理解為組件的“軀干”碾盐。

我們可以省略 render 之外的任何生命周期方法內(nèi)容的編寫,但是 render 函數(shù)不能省略揩局;但是 render 之外的生命周期方法的編寫毫玖,通常是為 render 服務(wù);“靈魂” 和 “軀干” 共同構(gòu)成了 React 組件完整的生命時(shí)間軸凌盯。

React15 生命周期

在 React15 中付枫,需要關(guān)注以下生命周期方法:

constructor()
componentWillReceiveProps()
shouldComponentUpdate()
componentWillMount()
componentWillUpdate()
componentDidUpdate()
componentDidMount()
render()
componentWillUnmount()

這些生命周期方法的關(guān)系:


lifecycle

下面的示例可以驗(yàn)證:

import React from "react"
import ReactDOM from "react-dom"

// 代碼源自 “深入淺出搞定 React -- 修言”

// 定義子組件
class LifeCycle extends React.Component {
  constructor(props) {
    console.log("進(jìn)入constructor")

    super(props)

    // state 可以在 constructor 里初始化
    this.state = { text: "子組件的文本" }
  }
  
  // 初始化渲染時(shí)調(diào)用
  componentWillMount() {
    console.log("componentWillMount方法執(zhí)行")
  }

// 初始化渲染時(shí)調(diào)用
  componentDidMount() {
    console.log("componentDidMount方法執(zhí)行")
  }

  // 父組件修改組件的props時(shí)會(huì)調(diào)用
  componentWillReceiveProps(nextProps) {
    console.log("componentWillReceiveProps方法執(zhí)行")
  }

  // 組件更新時(shí)調(diào)用
  shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate方法執(zhí)行")
    return true
  }

// 組件更新時(shí)調(diào)用
  componentWillUpdate(nextProps, nextState) {
    console.log("componentWillUpdate方法執(zhí)行")
  }

  // 組件更新后調(diào)用
  componentDidUpdate(nextProps, nextState) {
    console.log("componentDidUpdate方法執(zhí)行")
  }

  // 組件卸載時(shí)調(diào)用
  componentWillUnmount() {
    console.log("子組件的componentWillUnmount方法執(zhí)行")
  }

// 點(diǎn)擊按鈕,修改子組件文本內(nèi)容的方法
  changeText = () => {
    this.setState({
      text: "修改后的子組件文本"
    })
  }

  render() {
    console.log("render方法執(zhí)行")
    return (
      <div className="container">
        <button onClick={this.changeText} className="changeText">
          修改子組件文本內(nèi)容
        </button>
        <p className="textContent">{this.state.text}</p>
        <p className="fatherContent">{this.props.text}</p>
      </div>
    )
  }
}

// 定義 LifeCycle 組件的父組件
class LifeCycleContainer extends React.Component {
  // state 也可以像這樣用屬性聲明的形式初始化
  state = {
    text: "父組件的文本",
    hideChild: false
  }
  // 點(diǎn)擊按鈕驰怎,修改父組件文本的方法
  changeText = () => {
    this.setState({
      text: "修改后的父組件文本"
    })
  }

 // 點(diǎn)擊按鈕阐滩,隱藏(卸載)LifeCycle 組件的方法
  hideChild = () => {
    this.setState({
      hideChild: true
    })
  }

render() {
    return (
      <div className="fatherContainer">
        <button onClick={this.changeText} className="changeText">
          修改父組件文本內(nèi)容
        </button>
        <button onClick={this.hideChild} className="hideChild">
          隱藏子組件
        </button>
        {this.state.hideChild ? null : <LifeCycle text={this.state.text} />}
      </div>
    )
  }
}

ReactDOM.render(<LifeCycleContainer />, document.getElementById("root"))

掛載階段

組件掛載在一個(gè) React 組件的生命周期中只會(huì)發(fā)生一次,在這個(gè)過程中县忌,組件被初始化掂榔,最后被渲染到真實(shí) DOM;

掛載階段症杏,一個(gè) React 組件所經(jīng)歷的生命周期:


load
  • constructor():對(duì) this.state 初始化装获。
  • componentWillMount() :在 render 方法前被觸發(fā)。
  • render() :生成需要渲染的內(nèi)容并返回厉颤,不會(huì)操作真實(shí) DOM穴豫。真實(shí) DOM 的渲染由 ReactDOM.render 完成。
  • componentDidMount() :在渲染結(jié)束后被觸發(fā)逼友,此時(shí)可以訪問真實(shí) DOM 精肃。在這個(gè)生命周期中也可以做類似于異步請(qǐng)求、數(shù)據(jù)初始化的操作帜乞。

更新階段

更新階段司抱,一個(gè) React 組件所經(jīng)歷的生命周期:


update

componentWillReceiveProps

從圖中可以看出,由父組件觸發(fā)的更新和由組件自身觸發(fā)的更新對(duì)比挖函,多出了一個(gè)生命周期方法:componentWillReceiveProps(nextProps)状植。

nextProps 表示新 props 內(nèi)容,而現(xiàn)有的 props 可以通過 this.props 獲取怨喘,從而對(duì)比 props 的變化津畸。

如果父組件導(dǎo)致組件重新渲染,即使 props 沒有更改必怜,也會(huì)調(diào)用此方法(componentWillReceiveProps)肉拓。如果只想處理更改,請(qǐng)確保進(jìn)行當(dāng)前值與變更值的比較梳庆。

componentWillReceiveProps 并不是由 props 的變化觸發(fā)的暖途,而是由父組件的更新觸發(fā)的

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState)

由于 render 方法會(huì)進(jìn)行虛擬 DOM 的構(gòu)建和對(duì)比卑惜,比較耗時(shí)。為了避免不必要的 render 調(diào)用驻售,React 提供了 shouldComponentUpdate 生命周期方法露久。

根據(jù) shouldComponentUpdate() 的返回值,判斷 React 組件的輸出是否受當(dāng)前 state 或 props 更改的影響欺栗。默認(rèn)行為是 state 每次發(fā)生變化組件都會(huì)重新渲染毫痕。大部分情況下,你應(yīng)該遵循默認(rèn)行為迟几。

此方法僅作為性能優(yōu)化的方式而存在消请。不要企圖依靠此方法來“阻止”渲染,因?yàn)檫@可能會(huì)產(chǎn)生 bug类腮。你應(yīng)該考慮使用內(nèi)置的 PureComponent 組件臊泰,而不是手動(dòng)編寫 shouldComponentUpdate()PureComponent 會(huì)對(duì) props 和 state 進(jìn)行淺層比較蚜枢,并減少了跳過必要更新的可能性缸逃。

componentWillUpdate 和 componentDidUpdate

componentWillUpdaterender 前觸發(fā),和 componentWillMount類似祟偷,可以在里面做一些與真實(shí) DOM 不相關(guān)的操作察滑。
componentDidUpdate 在組件更新完成后觸發(fā),和 componentDidMount 類似修肠,可以在里面處理 DOM 操作贺辰;作為子組件更新完畢通知父組件的標(biāo)志。

卸載階段

組件銷毀嵌施,只有 componentWillUnmount() 生命周期饲化,可以在里面做一些釋放內(nèi)存,清理定時(shí)器等操作吗伤。

React16 生命周期

React 16.3 生命周期:

React16

示例代碼:

import React from "react"
import ReactDOM from "react-dom"

// 代碼源自 “深入淺出搞定 React -- 修言”

// 定義子組件
class LifeCycle extends React.Component {
  constructor(props) {
    console.log("進(jìn)入constructor")

    super(props)

    // state 可以在 constructor 里初始化
    this.state = { text: "子組件的文本" }
  }

// 初始化/更新時(shí)調(diào)用
  static getDerivedStateFromProps(props, state) {
    console.log("getDerivedStateFromProps方法執(zhí)行")
    return {
      fatherText: props.text
    }
  }

  // 初始化渲染時(shí)調(diào)用
  componentDidMount() {
    console.log("componentDidMount方法執(zhí)行")
  }

  // 組件更新時(shí)調(diào)用
  shouldComponentUpdate(prevProps, nextState) {
    console.log("shouldComponentUpdate方法執(zhí)行")
    return true
  }

// 組件更新時(shí)調(diào)用
  getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("getSnapshotBeforeUpdate方法執(zhí)行")
    return "haha"
  }

  // 組件更新后調(diào)用
  componentDidUpdate(nextProps, nextState, valueFromSnapshot) {
    console.log("componentDidUpdate方法執(zhí)行")
    console.log("從 getSnapshotBeforeUpdate 獲取到的值是", valueFromSnapshot)
  }

  // 組件卸載時(shí)調(diào)用
  componentWillUnmount() {
    console.log("子組件的componentWillUnmount方法執(zhí)行")
  }

// 點(diǎn)擊按鈕吃靠,修改子組件文本內(nèi)容的方法
  changeText = () => {
    this.setState({
      text: "修改后的子組件文本"
    })
  }

  render() {
    console.log("render方法執(zhí)行");
    return (
      <div className="container">
        <button onClick={this.changeText} className="changeText">
          修改子組件文本內(nèi)容
        </button>
        <p className="textContent">{this.state.text}</p>
        <p className="fatherContent">{this.props.text}</p>
      </div>
    )
  }
}

// 定義 LifeCycle 組件的父組件
class LifeCycleContainer extends React.Component {
  // state 也可以像這樣用屬性聲明的形式初始化
  state = {
    text: "父組件的文本",
    hideChild: false
  }

// 點(diǎn)擊按鈕,修改父組件文本的方法
  changeText = () => {
    this.setState({
      text: "修改后的父組件文本"
    })
  }

  // 點(diǎn)擊按鈕足淆,隱藏(卸載)LifeCycle 組件的方法
  hideChild = () => {
    this.setState({
      hideChild: true
    })
  }

render() {
    return (
      <div className="fatherContainer">
        <button onClick={this.changeText} className="changeText">
          修改父組件文本內(nèi)容
        </button>
        <button onClick={this.hideChild} className="hideChild">
          隱藏子組件
        </button>
        {this.state.hideChild ? null : <LifeCycle text={this.state.text} />}
      </div>
    )
  }
}

ReactDOM.render(<LifeCycleContainer />, document.getElementById("root"))

掛載階段

LoadCompare

componentWillMount vs getDerivedStateFromProps

對(duì)比于 React 15 廢棄了 componentWillMount 巢块,新增了 getDerivedStateFromProps

componentWillMount 的存在不僅“雞肋”而且危險(xiǎn)巧号,因此它不值得被“替代”族奢,而應(yīng)該直接廢棄。

getDerivedStateFromProps 的設(shè)計(jì)初衷是替換 componentWillReceiveProps丹鸿,它有且僅有一個(gè)作用:讓組件在 props 變化時(shí)派生/更新 state越走。

getDerivedStateFromProps 的方法簽名:

static getDerivedStateFromProps(props, state)
  • getDerivedStateFromProps 是一個(gè)靜態(tài)方法;不依賴組件實(shí)例;在這個(gè)方法里不能訪問 this廊敌。
  • 兩個(gè)參數(shù):propsstate铜跑,分別表示組件接收的來自父組件的 props 和自身的 state
  • 需要一個(gè)對(duì)象作為返回值骡澈;如果沒有指定返回值锅纺,React 會(huì)發(fā)出警告;React 需要用這個(gè)返回值來更新/派生組件的 stat秧廉;如果不需要伞广,最好直接省略這個(gè)方法,否則需要返回 null疼电。
  • 對(duì) state 的更新不是“覆蓋”,而是針對(duì)屬性的定向更新减拭。

更新階段

UpdateCompare

React 16.4 的掛載和卸載和 React 16.3 保持一致蔽豺,更新階段不同:

React 16.4 生命周期:

React16.4

  • 在 React 16.4 中,任何因素觸發(fā)的組件更新都會(huì)觸發(fā) getDerivedStateFromProps拧粪。
  • 在 React 16.3 中修陡,只有父組件的更新才會(huì)觸發(fā) getDerivedStateFromProps

getDerivedStateFromProps

  • getDerivedStateFromProps 是為了試圖替換 componentWillReceiveProp 而出現(xiàn)的可霎。
  • getDerivedStateFromProps 不能完全等同于 componentWillReceiveProps魄鸦。
    • 代替實(shí)現(xiàn)基于 props 派生 state。
    • 原則上癣朗,它能且只能做這一件事拾因。

為什么要用 getDerivedStateFromProps替換 componentWillReceiveProps

“合理的減法”
getDerivedStateFromProps 直接被定義為 static方法,使得在其方法內(nèi)部無法拿到組件實(shí)例的 this旷余,也就不能在里面執(zhí)行類似不合理的 this.setState (可能會(huì)導(dǎo)致死循環(huán))這類會(huì)產(chǎn)生副作用的操作绢记。

確保生命周期函數(shù)的行為可控可預(yù)測,從源頭上幫助開發(fā)者避免不合理的編碼正卧,同時(shí)也是為新的Fiber 架構(gòu)鋪路蠢熄。

componentWillUpdate vs getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps, prevState) {
  // ...
}
  • 執(zhí)行時(shí)機(jī)在 render 方法之后,真實(shí) DOM 更新之前
  • 可以獲得 DOM 更新前后的 stateprops 信息
  • 返回值將作為componentDidUpdate 的第三個(gè)參數(shù)

在實(shí)際編程中很少用到炉旷,但也有特殊場景需要签孔。

例如:實(shí)現(xiàn)一個(gè)內(nèi)容會(huì)發(fā)生變化的滾動(dòng)列表,要求根據(jù)滾動(dòng)列表的內(nèi)容是否發(fā)生變化窘行,來決定是否要記錄滾動(dòng)條的當(dāng)前位置饥追。

這個(gè)例子中要求我們對(duì)比更新前后的數(shù)據(jù)是否發(fā)生變化,還需要獲取真實(shí)的 DOM 位置信息抽高。

componentDidUpdate 配合編程:

// 組件更新時(shí)調(diào)用
getSnapshotBeforeUpdate(prevProps, prevState) {
  console.log("getSnapshotBeforeUpdate方法執(zhí)行")
  return "haha"
}

// 組件更新后調(diào)用
componentDidUpdate(prevProps, prevState, valueFromSnapshot) {
  console.log("componentDidUpdate方法執(zhí)行")
  console.log("從 getSnapshotBeforeUpdate 獲取到的值是", valueFromSnapshot)
}

getSnapshotBeforeUpdate 的設(shè)計(jì)初衷是為了 “與 componentDidUpdate 一起判耕,覆蓋過時(shí)的componentWillUpdate”。

為什么廢除 componentWillUpdate翘骂,是因?yàn)樗贿m合 Fiber 架構(gòu)壁熄。

卸載階段

與 React 15 完全一致

React 16 為何做出兩次改變

Fiber 架構(gòu)簡析

使 Virtual DOM 可以進(jìn)行增量式渲染

Fiber 會(huì)使原本同步的渲染過程變成異步的

在 React 16 之前帚豪,每次組件更新,React 都會(huì)構(gòu)建虛擬 DOM草丧,再與舊虛擬 DOM 對(duì)比 diff狸臣,最后對(duì)真實(shí) DOM 定向更新。

同步調(diào)用的調(diào)用棧非常深昌执,需要等到遞歸調(diào)用都返回后烛亦,整個(gè)渲染才算結(jié)束。

這個(gè)“漫長”的同步渲染過程不可被打斷懂拾,存在巨大風(fēng)險(xiǎn)煤禽;同步渲染一旦開始,會(huì)占據(jù)主線程岖赋,直到徹底完成檬果;在這個(gè)過程中,瀏覽器無法處理其他任務(wù)包括用戶交互唐断,甚至可能出現(xiàn)卡頓至卡死的風(fēng)險(xiǎn)选脊。

React 16 引入的 Fiber 架構(gòu),可以解決這個(gè)風(fēng)險(xiǎn):Fiber 會(huì)將一個(gè)大的更新任務(wù)拆解為多個(gè)小任務(wù)脸甘;每次執(zhí)行完成一個(gè)小任務(wù)恳啥,渲染線程都會(huì)交還主線程給瀏覽器,然后處理優(yōu)先級(jí)更高的工作丹诀,進(jìn)而避免同步渲染導(dǎo)致的卡頓钝的。

React 渲染的過程可以被中斷,可以將控制權(quán)交回瀏覽器忿墅,讓位給高優(yōu)先級(jí)的任務(wù)扁藕,瀏覽器空閑后再恢復(fù)渲染。

從 Fiber 架構(gòu)角度看生命周期

Fiber 架構(gòu)的重要特征就是渲染過程可以被中斷疚脐。根據(jù)這個(gè)特征亿柑,React 16 的生命周期被劃分為 Render 和 Commit 兩個(gè)階段,而 Commit 階段又被細(xì)分為 Pre-commit 和 Commit 階段棍弄。

Fiber

  • Render 階段:純凈且不包含副作用望薄。可能會(huì)被 React 暫停呼畸,中止或重新啟動(dòng)痕支。
  • Pre-commit 階段:可以讀取 DOM。
  • Commit 階段:可以使用 DOM蛮原,運(yùn)行副作用卧须,安排更新。

也就是說在 Render 階段允許被中斷,而 Commit 階段不能花嘶。原因很簡單笋籽,Render 階段的操作對(duì)于用戶不可感知,所以中斷椭员、重啟對(duì)于用戶而言是不可見的车海。而 Commit 階段的操作是對(duì)真實(shí) DOM 的渲染,不能隨意中斷隘击、重渲染侍芝。

React 16 “廢舊立新”背后的思考

Fiber 架構(gòu)下,Render 階段允許被暫停埋同、終止和重啟州叠。當(dāng)一個(gè)任務(wù)執(zhí)行一段后被中斷,下一次搶回渲染線程時(shí)莺禁,這個(gè)任務(wù)會(huì)“重復(fù)執(zhí)行一遍整個(gè)任務(wù)”而不是接著上一次執(zhí)行的地方留量。這導(dǎo)致了 Render 階段的生命周期方法有可能重復(fù)執(zhí)行。

React 16 廢棄的生命周期方法:

  • componentWillMount
  • componentWillUpdate
  • componentWillReceiveProps

這些方法都處于 Render 階段哟冬,而且這些方法常年被濫用,在重復(fù)執(zhí)行的過程中存在很大的風(fēng)險(xiǎn)忆绰。

我們的編碼中的一些不好的習(xí)慣浩峡,在 “componentWill” 開頭的生命周期里做一些事情:

  • setState()
  • fetch 異步請(qǐng)求
  • 操作真實(shí) DOM
  • ...

這些操作的問題:

  1. 可以轉(zhuǎn)移到其他生命周期(componentDid...)里去做
  2. Fiber 架構(gòu)下,可能導(dǎo)致非常嚴(yán)重的 Bug
  3. 在 React 15 中也有出現(xiàn)過問題(在 componentWillReceivePropscomponentWillUpdate里濫用 setState 導(dǎo)致重渲染死循環(huán))

總結(jié)

  • React 16 改造生命周期的主要原因是為了配合 Fiber 架構(gòu)帶來的異步渲染機(jī)制错敢。
  • 針對(duì)生命周期中長期被濫用的部分推出了具有強(qiáng)制性的最佳實(shí)踐翰灾。
  • 確保了 Fiber 架構(gòu)下的數(shù)據(jù)和視圖的安全,以及確保了生命周期方法的行為更加可控稚茅、可預(yù)測纸淮。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市亚享,隨后出現(xiàn)的幾起案子咽块,更是在濱河造成了極大的恐慌,老刑警劉巖欺税,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侈沪,死亡現(xiàn)場離奇詭異,居然都是意外死亡晚凿,警方通過查閱死者的電腦和手機(jī)亭罪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歼秽,“玉大人应役,你說我怎么就攤上這事。” “怎么了箩祥?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵院崇,是天一觀的道長。 經(jīng)常有香客問我滥比,道長亚脆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任盲泛,我火速辦了婚禮濒持,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寺滚。我一直安慰自己柑营,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布村视。 她就那樣靜靜地躺著官套,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚁孔。 梳的紋絲不亂的頭發(fā)上奶赔,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音杠氢,去河邊找鬼站刑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鼻百,可吹牛的內(nèi)容都是我干的绞旅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼温艇,長吁一口氣:“原來是場噩夢啊……” “哼因悲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起勺爱,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤晃琳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后邻寿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝎土,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年绣否,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了誊涯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蒜撮,死狀恐怖暴构,靈堂內(nèi)的尸體忽然破棺而出跪呈,到底是詐尸還是另有隱情,我是刑警寧澤取逾,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布耗绿,位于F島的核電站,受9級(jí)特大地震影響砾隅,放射性物質(zhì)發(fā)生泄漏误阻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一晴埂、第九天 我趴在偏房一處隱蔽的房頂上張望究反。 院中可真熱鬧,春花似錦儒洛、人聲如沸精耐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卦停。三九已至,卻和暖如春恼蓬,著一層夾襖步出監(jiān)牢的瞬間惊完,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國打工处硬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留专执,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓郁油,卻偏偏與公主長得像,于是被迫代替她去往敵國和親攀痊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子桐腌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容