React useState使用完整教程(譯)

useState是一個(gè)Hook函數(shù),讓你在函數(shù)組件中擁有state變量可缚。它接收一個(gè)初始化的state霎迫,返回是一個(gè)數(shù)組,數(shù)組里有兩個(gè)元素帘靡,第一個(gè)元素是當(dāng)前狀態(tài)值和另一個(gè)更新該值的方法知给。
本教程主要是針對(duì)于React中的useState做一個(gè)詳細(xì)的描述,它等同于函數(shù)組件中的this.state/this.setState描姚,我們將會(huì)圍繞下面的問(wèn)題逐一解析:

  • React中的類組件和函數(shù)組件
  • React.useState hook做了什么
  • 在React中聲明狀態(tài)
  • React Hooks: Update State
  • 在useState hook中使用對(duì)象作為狀態(tài)變量
  • React Hooks中如何更新嵌套對(duì)象狀態(tài)
  • 多個(gè)狀態(tài)變量還是一個(gè)狀態(tài)對(duì)象
  • 使用useState的規(guī)則
  • useReducer Hook的使用

如果您是剛開始學(xué)習(xí)使用useState涩赢,請(qǐng)查看官方文檔或者該視頻教程

React中的類組件和函數(shù)組件

React有兩種類型的組件:類組件和函數(shù)組件轩勘。
類組件是繼承React.Component的ES6類筒扒,它有自己的狀態(tài)和生命周期函數(shù):

class Message extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: ""
    };
  }

  componentDidMount() {
    /*...*/
  }

  render() {
    return <div>{this.state.message}</div>
  }
}

函數(shù)組件是一個(gè)函數(shù),它能接收任何組件的屬性作為參數(shù)绊寻,并且可以返回有效的JSX花墩。

function Message(props) {
  return <div>{props.message} </div>
}
//或者使用箭頭函數(shù)
const Message = (props) => <div>{props.message}</div>

正如所看到的,函數(shù)組件沒(méi)有任何狀態(tài)和生命周期方法澄步。不過(guò)冰蘑,在React16.8,我們可以使用Hooks村缸。
React Hooks是方法祠肥,它可以給函數(shù)組件添加狀態(tài)變量,并且可以模擬類組件的生命周期方法梯皿。他們傾向以use作為Hook名的開始仇箱。

React.useState hook做了什么

正如之前了解的,useState可以給函數(shù)組件添加狀態(tài)东羹,函數(shù)組件中的useState可以生成一系列與其組件相關(guān)聯(lián)的狀態(tài)剂桥。

類組件中的狀態(tài)總是一個(gè)對(duì)象,不過(guò)Hooks中的狀態(tài)可以是任意類型百姓。每個(gè)state可以有單一的值,也可以是一個(gè)對(duì)象况木、數(shù)組垒拢、布爾值或者能想到的任意類型。

So火惊,你會(huì)什么時(shí)候用useStateHook呢求类?它對(duì)組件自身的狀態(tài)很有用,然而大項(xiàng)目可能會(huì)需要另外的狀態(tài)管理方案屹耐。

React聲明狀態(tài)

useStateReact的命名輸出出尸疆,因此你可以這么寫:

  React.useState

或者可以直接這么寫:

import React, { useState } from "react";

然而不像在類組件里聲明狀態(tài)對(duì)象那樣,useState允許聲明多個(gè)狀態(tài)變量:

import React from "react";

class Message extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: "",
      list: "",
    }
  }
  /*...*/
}

useStateHook一次只能聲明一個(gè)狀態(tài)變量,不過(guò)這個(gè)狀態(tài)變量可以是任意類型的:

import React, { useState } from "react";

const Message = () => {
  const messageState = useState("");
  const listState = useState([]);
}

useState接收狀態(tài)的初始值作為一個(gè)參數(shù)寿弱。
正如之前例子展示的犯眠,可以直接給函數(shù)傳遞,也可以使用函數(shù)來(lái)延遲初始化該變量(當(dāng)初始化狀態(tài)基于一次昂貴的計(jì)算症革,這種方式是很有用的):

const Message = () => {
  const messageState = useState(() => expensiveComputation());
  /*...*/
}

初始化的值僅僅會(huì)在第一次渲染時(shí)被賦值(如果他是一個(gè)函數(shù)筐咧,也是會(huì)在初次渲染時(shí)執(zhí)行)。
在后續(xù)的更新中(由于組件本身的狀態(tài)更改或者是說(shuō)父組件導(dǎo)致的變化)噪矛,useStateHook參數(shù)(初始值)將會(huì)被忽略量蕊,當(dāng)前的值將會(huì)被使用。
理解它是非常重要的艇挨,舉個(gè)例子残炮,如果你想更新基于組件接收的新屬性的狀態(tài):

const Message = (props) => {
  const messageState = useState(props.message);
}

只單獨(dú)使用useState不會(huì)工作的,因?yàn)樗膮?shù)僅僅在第一次生效缩滨,并不是每次屬性更改時(shí)生效(可以結(jié)合useEffect使用势就,具體查看該回答
不過(guò),useState不是像之前所說(shuō)的僅僅返回一個(gè)變量楷怒。
它返回的是一個(gè)數(shù)組蛋勺,第一個(gè)元素是狀態(tài)變量,第二個(gè)元素是更新該變量值的方法鸠删。

const Message= () => {
  const messageState = useState("");
  const message = messageState[0]; // 是一個(gè)空字符串
  const setMessage = messageState[1]; // 是一個(gè)方法
}

一般我們會(huì)選擇數(shù)組解構(gòu)的方式來(lái)簡(jiǎn)化上述代碼:

const Message = () => {
  const [message, setMessage] = useState("");
}

在函數(shù)組件中可以像其他變量一樣使用狀態(tài)變量:

const Message = () => {
  const [message, setMessage] = useState("");
  return <p>{message}</p>;
}

但是為什么useState會(huì)返回一個(gè)數(shù)組呢抱完?
因?yàn)榕c對(duì)象相比、數(shù)組是非常靈活且容易使用刃泡。
如果這個(gè)方法返回的是一個(gè)包括一系列屬性集的對(duì)象巧娱,那么就不能很容易自定義變量名,比如:

// 沒(méi)有使用對(duì)象解構(gòu)
const messageState = useState( '' );
const message = messageState.state;
const setMessage = messageState;

//使用對(duì)象解構(gòu)
const { state: message, setState: setMessage } = useState( '' );
const { state: list, setState: setList } = useState( [] );

React Hooks: 更新狀態(tài)

useState返回的第二個(gè)元素是一個(gè)方法烘贴,它用新值來(lái)更新狀態(tài)變量禁添。
舉個(gè)??,使用輸入框在每次改變時(shí)更新狀態(tài)變量示例

const Message = () => {
  const [message, setMessage] = useState( '' );

  return (
    <div>
      <input
         type="text"
         value={message}
         placeholder="Enter a message"
         onChange={e => setMessage(e.target.value)}
       />
      <p>
        <strong>{message}</strong>
      </p>
    </div>
  );
};

然而桨踪,這個(gè)更新函數(shù)不會(huì)立即更新值老翘。相反它會(huì)排隊(duì)等待更新操作。在重新渲染組件后锻离,useState的參數(shù)將被忽略铺峭,這個(gè)更新方法將會(huì)返回最新的值。
如果你需要用之前的值來(lái)更新狀態(tài)汽纠,你一定得傳遞一個(gè)接收之前值的方法來(lái)返回新值示例

const Message = () => {
  const [message, setMessage] = useState("");

  return (
    <div>
      <input
        type="text"
        value={message}
        placeholder="Enter a message"
        onChange={(e) => {
          const val = e.target.value;
          setMessage((prev) => prev + val);
        }}
      />
      <p>
        <strong>{message}</strong>
      </p>
    </div>
  );
};

useState hook中使用對(duì)象作為狀態(tài)變量

當(dāng)使用對(duì)象時(shí)卫键,需要記住的是:

  1. 不可變的重要性
  2. useState返回的更新方法不是像類組件中的setState合并對(duì)象

關(guān)于第一點(diǎn),如果你是用相同的值作為當(dāng)前值來(lái)更新state(React使用的Object.is來(lái)做比較)虱朵,React不會(huì)觸發(fā)更新的莉炉。

當(dāng)使用對(duì)象時(shí)钓账,很容易出現(xiàn)下面的錯(cuò)誤示例,輸入框不能輸入文本:

const MessageOne = () => {
  const [messageObj, setMessageObj] = useState({ message: "" });

  return (
    <div>
      <input
        type="text"
        value={messageObj.message}
        placeholder="Enter a message"
        onChange={(e) => {
          messageObj.message = e.target.value;
          setMessageObj(messageObj);
        }}
      />
      <p>
        <strong>{messageObj.message}</strong>
      </p>
    </div>
  );
};

上面的例子沒(méi)有創(chuàng)建一個(gè)新對(duì)象絮宁,而是改變已經(jīng)存在的狀態(tài)對(duì)象梆暮。對(duì)于React來(lái)說(shuō),它們是同一個(gè)對(duì)象羞福。為了正常運(yùn)行惕蹄,我們創(chuàng)建一個(gè)新對(duì)象示例

onChange={(e) => {
  const newMessageObj = { message: e.target.value };
  setMessageObj(newMessageObj);
}}

這個(gè)讓我們看到了你需要記住的第二件事情。
當(dāng)你創(chuàng)建一個(gè)狀態(tài)變量時(shí)治专,類組件中的this.setState 自動(dòng)合并更新對(duì)象卖陵,而函數(shù)組件中useState的更新方法則是直接替換對(duì)象 。
繼續(xù)上面的例子张峰,如果我們給message對(duì)象添加一個(gè)id屬性泪蔫,將會(huì)發(fā)生什么呢示例

const MessageThree = () => {
  const [messageObj, setMessageObj] = useState({ message: "", id: 1 });

  return (
    <div>
      <input
        type="text"
        value={messageObj.message}
        placeholder="Enter a message"
        onChange={(e) => {
          const newMessageObj = { message: e.target.value };
          setMessageObj(newMessageObj);
        }}
      />
      <p>
        <strong>
          {messageObj.id}: {messageObj.message}
        </strong>
      </p>
    </div>
  );
};

當(dāng)只更新message屬性時(shí),React將替換原先的狀態(tài)值{ message: '', id: 1 }喘批,當(dāng)觸發(fā)onChange屬性時(shí)撩荣,狀態(tài)值將僅僅包含message屬性:

{message: "····"} // id屬性丟失了

當(dāng)然,通過(guò)替換的對(duì)象和擴(kuò)展運(yùn)算之前的對(duì)象結(jié)合作為參數(shù)也可以在函數(shù)組件中復(fù)制setState()的行為示例

onChange={(e) => {
  const val = e.target.value;
  setMessageObj((prevState) => {
    return { ...prevState, message: val };
  });
}}

...prevState會(huì)得到對(duì)象所有的屬性饶深,message: val會(huì)重新賦值給message屬性餐曹。

當(dāng)然使用Object.assign也會(huì)得到相同的結(jié)果(需要?jiǎng)?chuàng)建新對(duì)象)示例

//使用Object.assign
setMessageObj((prevState) => {
  return Object.assign({}, prevState, { message: val });
});          

不過(guò)擴(kuò)展運(yùn)算可以簡(jiǎn)化這個(gè)操作,而且也可以應(yīng)用到數(shù)組上敌厘。
一般來(lái)講台猴,當(dāng)在數(shù)組上使用時(shí),擴(kuò)展運(yùn)算移除了括號(hào)俱两,你可以用舊數(shù)組中的值創(chuàng)建另一個(gè)數(shù)組:

[
  ...['a', 'b', 'c'],
  'd'
]
// Is equivalent to
[ 'a', 'b', 'c','d']

再來(lái)個(gè)??饱狂,如何用數(shù)組來(lái)使用useState示例
需要注意的是,處理多維數(shù)組時(shí)需要謹(jǐn)慎的使用擴(kuò)展運(yùn)算宪彩,因?yàn)榭赡茏罱K的結(jié)果不是你所期待的休讳。
所以這個(gè)時(shí)候,我們就需要考慮使用對(duì)象作為狀態(tài)尿孔。

React Hooks中如何更新嵌套對(duì)象狀態(tài)

JS中俊柔,多維數(shù)組是數(shù)組里嵌套數(shù)組:

[
  ['value1','value2'],
  ['value3','value4']
]

你可以在用它們來(lái)把你所有的狀態(tài)變量集中在一個(gè)地方,然而活合,為了這個(gè)目的雏婶,最好使用內(nèi)嵌對(duì)象:

{
  'row1' : {
    'key1' : 'value1',
    'key2' : 'value2'
  },
  'row2' : {
    'key3' : 'value3',
    'key4' : 'value4'
  }
}

當(dāng)使用內(nèi)嵌對(duì)象和多維數(shù)組時(shí),有一個(gè)問(wèn)題是Object.assign和擴(kuò)展運(yùn)算是創(chuàng)建了一個(gè)淺拷貝并非是深拷貝芜辕。

當(dāng)拷貝數(shù)組時(shí)尚骄,擴(kuò)展運(yùn)算僅僅做了一層的拷貝块差,因此侵续,對(duì)于多維數(shù)組來(lái)說(shuō)倔丈,使用它是不合適的,就像下面例子中所示(使用Object.assign()和擴(kuò)展元算結(jié)果都是true):

let a = [[1], [2], [3]];
let b = [...a];
b.shift().shift(); // 1
//此時(shí)數(shù)組a的結(jié)果是[[], [2], [3]]

StackOverflow關(guān)于上面的例子提供了一個(gè)比較好的解釋状蜗,不過(guò)目前重要的是需五,當(dāng)使用內(nèi)嵌對(duì)象時(shí),我們不能用擴(kuò)展運(yùn)算來(lái)更新狀態(tài)對(duì)象轧坎。

再舉個(gè)??

const [messageObj, setMessageObj] = useState({
  author: "",
  message: {
    id: 1,
    text: "",
  }
});

來(lái)宏邮,先看看更新text字段的錯(cuò)誤方式示例

//錯(cuò)誤, 文本更改后,messageObj的值是{author: "", message: {id: 1, text: ""}, text: "*"}
setMessageObj((prevState) => ({
  ...prevState,
  text: val,
}));

//錯(cuò)誤缸血,文本更改后messageObj值是{id: "*", text: "*"}
setMessageObj((prevState) => ({
  ...prevState.message,
  text: val
}));

//錯(cuò)誤蜜氨,文本更改后,messageObj的值是{author: "", message: {text: "*"}}捎泻,缺少id屬性
setMessageObj((prevState) => ({
  ...prevState,
  message: {
    text: val,
  }
}));

為了能正確的更新text屬性飒炎,我們需要拷貝一個(gè)原始對(duì)象,這個(gè)新對(duì)象包括整個(gè)原始對(duì)象的所有屬性:

setMessageObj((prevState) => ({
  ...prevState,  //賦值第一層的key值
   message: {  //創(chuàng)建包含更新key值的對(duì)象
    ...prevState.message, //復(fù)制包含key值的對(duì)象
    text: val,  //給需要更新的字段重新賦值
  }
}));

以同樣的方式笆豁,我們也可以更新author字段:

setMessageObj((prevState) => ({
  author: "Joe",
  message: { ...prevState.message },
}));

如果message對(duì)象變化了郎汪,則用以下的方式:

setMessageObj((prevState) => ({
  author: "Joe",
  message: { 
    ...prevState.message, 
    text: val, 
  },
}));

聲明多個(gè)狀態(tài)變量還是一個(gè)狀態(tài)對(duì)象

當(dāng)你的應(yīng)用中使用多個(gè)字段或值作為狀態(tài)變量時(shí)蜒滩,你可以選擇組織多個(gè)變量:

const [id, setId] = useState(-1);
const [message, setMessage] = useState('');
const [author, setAuthor] = useState('');

或者使用一個(gè)對(duì)象狀態(tài)變量:

const [messageObj, setMessage] = useState({ 
  id: 1, 
  message: '', 
  author: '' 
});

不過(guò)班巩,需要謹(jǐn)慎的使用復(fù)雜數(shù)據(jù)結(jié)構(gòu)(內(nèi)嵌對(duì)象)的狀態(tài)對(duì)象豺撑,考慮下這個(gè)?? :

const [messageObj, setMessage] = useState({
  input: {
    author: {
      id: -1,
      author: {
        fName:'',
        lName: ''
      }
    },
    message: {
      id: -1,
      text: '',
      date: new Date(),
    }
  }
});

如果你需要更新嵌套在對(duì)象深處的指定字段時(shí)今艺,你必須復(fù)制所有其他對(duì)象和包含該指定字段的的對(duì)象的鍵值對(duì)一起復(fù)制:

setMessage(prevState => ({
  input: {
    ...prevState.input,
    message: {
      ...prevState.input.message, 
      text: '***',
    }
  }
}));

在某些情況下谓传,拷貝深度內(nèi)嵌對(duì)象是比較昂貴的裆操,因?yàn)镽eact可能會(huì)依賴那些沒(méi)有改變過(guò)的字段值重新渲染你應(yīng)用的部分內(nèi)容窗宇。
對(duì)于這個(gè)原因厌处,首先要做的是嘗試扁平化你的對(duì)象录豺。需要關(guān)注的是朦肘,React官方推薦根據(jù)哪些值傾向于一起變化,將狀態(tài)分割成多個(gè)狀態(tài)變量双饥。
如果這個(gè)不可能的話媒抠,推薦使用第三方庫(kù)來(lái)幫助你使用不可變對(duì)象,例如immutable.js或者 immer

useState使用規(guī)則

useState和所有的Hooks一樣咏花,都遵循同樣的規(guī)則:

  • 在頂層調(diào)用Hooks
  • 在React函數(shù)中調(diào)用Hooks

第二個(gè)規(guī)則很容易理解趴生,不要在類組件中使用useState

或者在常規(guī)JS方法中(不能在一個(gè)方法組件中被調(diào)用的):


如果項(xiàng)目中有ESLint的話, 則可以看到對(duì)應(yīng)錯(cuò)誤提示昏翰;如果沒(méi)有苍匆,則可以從該文檔中看到出現(xiàn)的錯(cuò)誤提示

第一個(gè)規(guī)則指的是:即使在函數(shù)組件內(nèi)部棚菊,不能在循環(huán)浸踩、條件或者內(nèi)嵌方法中調(diào)用useState,因?yàn)镽eact依賴于useState函數(shù)被調(diào)用的順序來(lái)獲取特定變量的正確值统求。
在這方面检碗,常見的錯(cuò)誤是据块,在if語(yǔ)句使用useState(它們不是每次都被執(zhí)行的):

if (condition) { // 有時(shí)它會(huì)執(zhí)行,導(dǎo)致useState的調(diào)用順序發(fā)生變化
  const [message, setMessage] = useState( '' );
  setMessage( aMessage );  
}
const [list, setList] = useState( [] );
setList( [1, 2, 3] );

函數(shù)組件中會(huì)多次調(diào)用useState或者其他的Hooks折剃。每個(gè)Hook是存儲(chǔ)在鏈表中的另假,而且有一個(gè)變量來(lái)追蹤當(dāng)前執(zhí)行的Hook。
當(dāng)useState被執(zhí)行時(shí)怕犁,當(dāng)前Hook的狀態(tài)被讀缺呃骸(第一次渲染期間是被初始化),之后奏甫,變量被改變?yōu)橹赶蛳乱粋€(gè)Hook戈轿。
這也就是為什么總是始終保持Hook相同的調(diào)用順序是很重要的。否則的話阵子,狀態(tài)值就會(huì)屬于另一個(gè)狀態(tài)變量凶杖。

總體來(lái)說(shuō),這兒有一個(gè)例子來(lái)一步步說(shuō)明它是如何工作的:

  1. React初始化Hook鏈表款筑,并且用一個(gè)變量追蹤當(dāng)前Hook
  2. React首次調(diào)用你的組件
  3. React發(fā)現(xiàn)了useState的調(diào)用智蝠,創(chuàng)建了一個(gè)新的Hook對(duì)象(帶有初始狀態(tài)),將當(dāng)前Hook變量指向該Hook對(duì)象奈梳,將該對(duì)象添加到Hooks鏈表中杈湾,然后返回一個(gè)帶有初始值和更新狀態(tài)方法的數(shù)組
  4. React發(fā)現(xiàn)另一個(gè)useState的調(diào)用,重復(fù)上面的步驟攘须,存儲(chǔ)新的hook對(duì)象漆撞,改變當(dāng)前Hook變量。
  5. 組件狀態(tài)發(fā)生變化
  6. React給要處理的隊(duì)列發(fā)送新的狀態(tài)更新操作(執(zhí)行useState返回的方法)
  7. React決定組件是否需要重新渲染
  8. React重置當(dāng)前Hook變量于宙,并且調(diào)用組件
  9. React發(fā)現(xiàn)了一個(gè)useState的調(diào)用浮驳,但此時(shí),在Hooks鏈表第一位置已經(jīng)有一個(gè)Hook捞魁,它僅僅改變了當(dāng)前Hook變量至会,返回一個(gè)帶狀態(tài)值和更新狀態(tài)方法的數(shù)組
  10. React發(fā)現(xiàn)另一個(gè)useState的調(diào)用,因?yàn)榈诙€(gè)位置有一個(gè)Hook了谱俭,它再次僅僅改變了當(dāng)前Hook變量奉件,返回一個(gè)帶狀態(tài)值和更新狀態(tài)方法的數(shù)組
    這是一個(gè)簡(jiǎn)單的useState工作流程,具體可以看ReactFiberHooks源碼

useReducerHook的使用

對(duì)于很多高級(jí)使用情況昆著,我們可以使用useReducerHook來(lái)代替useState县貌。當(dāng)處理復(fù)雜的狀態(tài)邏輯時(shí),它是很有用的凑懂。比如包含多個(gè)子值或者狀態(tài)依賴之前的值煤痕。
Look,看下如何使用useReducerHook,示例:

const [state, dispatch] = useReducer(reducer, initialArgument, init);
//useReducer返回一個(gè)帶有當(dāng)前狀態(tài)值和dispatch方法的數(shù)組摆碉。如果你使用過(guò)Redux祟敛,這個(gè)就得心應(yīng)手了。

useState兆解,你調(diào)用更新狀態(tài)的方法,然而useReducer中跑揉,你調(diào)用dispatch方法锅睛,然后傳遞給它一個(gè)action,eg: 至少是帶有一個(gè)type屬性的對(duì)象历谍。

dispatch({type:"increase"})

一般來(lái)講现拒,一個(gè)action對(duì)象也會(huì)有其他的屬性,eg: {action: "increase", payload: "10"}望侈。
然而傳遞一個(gè)action對(duì)象并不是絕對(duì)的印蔬,具體參考Redux

總結(jié)

uesState是一個(gè)Hook函數(shù),它讓你可以在組件中擁有狀態(tài)變量脱衙,你可以給這個(gè)方法傳遞初始值侥猬,并且返回一個(gè)當(dāng)前狀態(tài)值的變量(不一定是初始值)和另一個(gè)更新該值的方法。

這兒有一些需要記住的關(guān)鍵的點(diǎn):

  • 更新方法不會(huì)立即更新值
  • 如果你需要用到之前的值更新狀態(tài)捐韩,你必須將之前的值傳遞給該方法退唠,則它會(huì)返回一個(gè)更新后的值,eg: setMessage(previousVal => previousVal + currentVal)
  • 如果你使用同樣的值作為當(dāng)前狀態(tài)荤胁,則React不會(huì)觸發(fā)重新渲染瞧预。(React是用Object.is來(lái)做比較的)
  • useState不像類組件中的this.setState合并對(duì)象,它是直接替換對(duì)象仅政。
  • useState和所有的hooks遵循相同的規(guī)則垢油,特別是,注意這些函數(shù)的調(diào)用順序圆丹。(可以借助 ESLint plugin滩愁,它會(huì)幫助我們強(qiáng)制實(shí)施這些規(guī)則)

相關(guān)文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辫封,隨后出現(xiàn)的幾起案子惊楼,更是在濱河造成了極大的恐慌,老刑警劉巖秸讹,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件檀咙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡璃诀,警方通過(guò)查閱死者的電腦和手機(jī)弧可,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)劣欢,“玉大人棕诵,你說(shuō)我怎么就攤上這事裁良。” “怎么了校套?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵价脾,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我笛匙,道長(zhǎng)侨把,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任妹孙,我火速辦了婚禮秋柄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蠢正。我一直安慰自己骇笔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布嚣崭。 她就那樣靜靜地躺著笨触,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雹舀。 梳的紋絲不亂的頭發(fā)上旭旭,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音葱跋,去河邊找鬼持寄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛娱俺,可吹牛的內(nèi)容都是我干的稍味。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼荠卷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼模庐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起油宜,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤掂碱,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后慎冤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疼燥,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年蚁堤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了醉者。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖撬即,靈堂內(nèi)的尸體忽然破棺而出立磁,到底是詐尸還是另有隱情,我是刑警寧澤剥槐,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布唱歧,位于F島的核電站,受9級(jí)特大地震影響粒竖,放射性物質(zhì)發(fā)生泄漏颅崩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一温圆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧孩革,春花似錦岁歉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至饱搏,卻和暖如春非剃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背推沸。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工备绽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鬓催。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓肺素,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親宇驾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子倍靡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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