Springboot+react+dva入門實戰(zhàn)—前后端傳值

8.jpg

前言:

本文分為2個部分:

1.前半部分為5個前置知識點,簡要介紹了React中的props和state、dva中connect膝迎、dispatch方法

2.后半部分從一個項目實例入手介紹react+dva前后端傳值的過程,涉及models介劫、action峰弹、view理卑、service距辆。

Tips:配合官網(wǎng)看例子效果更好:

react官網(wǎng):https://reactjs.org/

dva-github:dvajs/dva

1.React中的props和state的區(qū)別

參考:https://segmentfault.com/q/1010000008340434
在任何應(yīng)用中,數(shù)據(jù)都是必不可少的暮刃。我們需要直接的改變頁面上一塊的區(qū)域來使得視圖的刷新挑格,或者間接地改變其他地方的數(shù)據(jù)。React的數(shù)據(jù)是自頂向下單向流動的沾歪,即從父組件到子組件中漂彤,組件的數(shù)據(jù)存儲在props和state中,這兩個屬性有啥子區(qū)別呢灾搏?

props

React的核心思想就是組件化思想挫望,頁面會被切分成一些獨立的、可復(fù)用的組件狂窑。
組件從概念上看就是一個函數(shù)媳板,可以接受一個參數(shù)作為輸入值,這個參數(shù)就是props泉哈,所以可以把props理解為從外部傳入組件內(nèi)部的數(shù)據(jù)蛉幸。由于React是單向數(shù)據(jù)流,所以props基本上也就是從服父級組件向子組件傳遞的數(shù)據(jù)丛晦。

用法

假設(shè)我們現(xiàn)在需要實現(xiàn)一個列表奕纫,根據(jù)React組件化思想,我們可以把列表中的行當(dāng)做一個組件烫沙,也就是有這樣兩個組件:和匹层。
先看看

import Item from “./item”;
export default class ItemList extends React.Component{
  const itemList = data.map(item => <Item item=item />);
  render(){
    return (
      {itemList}
    )
  }
}

列表的數(shù)據(jù)我們就暫時先假設(shè)是放在一個data變量中,然后通過map函數(shù)返回一個每一項都是的數(shù)組锌蓄,也就是說這里其實包含了data.length個組件升筏,數(shù)據(jù)通過在組件上自定義一個參數(shù)傳遞。當(dāng)然瘸爽,這里想傳遞幾個自定義參數(shù)都可以您访。

具體是這樣的:

export default class Item extends React.Component{
  render(){
    return (
      <li>{this.props.item}</li>
    )
  }
}

在render函數(shù)中可以看出,組件內(nèi)部是使用this.props來獲取傳遞到該組件的所有數(shù)據(jù)剪决,它是一個對象灵汪,包含了所有你對這個組件的配置,現(xiàn)在只包含了一個item屬性昼捍,所以通過this.props.item來獲取即可识虚。

只讀性

props經(jīng)常被用作渲染組件和初始化狀態(tài),當(dāng)一個組件被實例化之后妒茬,它的props是只讀的担锤,不可改變的。如果props在渲染過程中可以被改變乍钻,會導(dǎo)致這個組件顯示的形態(tài)變得不可預(yù)測肛循。只有通過父組件重新渲染的方式才可以把新的props傳入組件中铭腕。

默認(rèn)參數(shù)

在組件中,我們最好為props中的參數(shù)設(shè)置一個defaultProps多糠,并且制定它的類型累舷。比如,這樣:

Item.defaultProps = {
  item: ‘Hello Props’,
};
Item.propTypes = {
  item: PropTypes.string,
};

關(guān)于propTypes夹孔,可以聲明為以下幾種類型:

optionalArray: PropTypes.array,

optionalBool: PropTypes.bool,

optionalFunc: PropTypes.func,

optionalNumber: PropTypes.number,

optionalObject: PropTypes.object,

optionalString: PropTypes.string,

optionalSymbol: PropTypes.symbol,

注意被盈,bool和func是簡寫。

這些知識基礎(chǔ)數(shù)據(jù)類型搭伤,還有一些復(fù)雜的只怎,附上鏈接:

https://facebook.github.io/react/docs/typechecking-with-proptypes.html

總結(jié)

props是一個從外部傳進(jìn)組件的參數(shù),主要作為就是從父組件向子組件傳遞數(shù)據(jù)怜俐,它具有可讀性和不變性身堡,只能通過外部組件主動傳入新的props來重新渲染子組件,否則子組件的props以及展現(xiàn)形式不會改變拍鲤。

state

state是什么呢贴谎?

  • State is similar to props, but it is private and fully controlled by the component.

一個組件的顯示形態(tài)可以由數(shù)據(jù)狀態(tài)和外部參數(shù)所決定吊洼,外部參數(shù)也就是props罐柳,而數(shù)據(jù)狀態(tài)就是state。

export default class ItemList extends React.Component{
  constructor(){
    super();
    this.state = {
      itemList:‘一些數(shù)據(jù)’,
    }
  }
  render(){
    return (
      {this.state.itemList}
    )
  }
}

首先甥绿,在組件初始化的時候绞幌,通過this.state給組件設(shè)定一個初始的state,在第一次render的時候就會用這個數(shù)據(jù)來渲染組件莲蜘。

setState

state不同于props的一點是帘营,state是可以被改變的。不過芬迄,不可以直接通過this.state=的方式來修改问顷,而需要通過this.setState()方法來修改state禀梳。

比如,我們經(jīng)常會通過異步操作來獲取數(shù)據(jù)算途,我們需要在didMount階段來執(zhí)行異步操作:

componentDidMount(){
  fetch(‘url’)
    .then(response => response.json())
    .then((data) => {
      this.setState({itemList:item});  
    }
}

當(dāng)數(shù)據(jù)獲取完成后塞耕,通過this.setState來修改數(shù)據(jù)狀態(tài)。當(dāng)我們調(diào)用this.setState方法時嘴瓤,React會更新組件的數(shù)據(jù)狀態(tài)state莉钙,并且重新調(diào)用render方法筛谚,也就是會對組件進(jìn)行重新渲染。

注意:

通過this.state=來初始化state蚊伞,使用this.setState來修改state吮铭,constructor是唯一能夠初始化的地方厚柳。setState接受一個對象或者函數(shù)作為第一個參數(shù)沐兵,只需要傳入需要更新的部分即可,不需要傳入整個對象碳想,比如:

export default class ItemList extends React.Component{
  constructor(){
    super();
    this.state = {
      name:‘a(chǎn)xuebin’,
      age:25,
    }
  }
  componentDidMount(){
    this.setState({age:18})  
  }
}

在執(zhí)行完setState之后的state應(yīng)該是{name:’axuebin’,age:18}毁靶。
setState還可以接受第二個參數(shù),它是一個函數(shù)预吆,會在setState調(diào)用完成并且組件開始重新渲染時被調(diào)用,可以用來監(jiān)聽渲染是否完成:

this.setState({
  name:‘xb’
},()=>console.log(‘setState finished’))

總結(jié)

state的主要作用是用于組件保存岩遗、控制以及修改自己的狀態(tài)凤瘦,它只能在constructor中初始化,它算是組件的私有屬性蔬芥,不可通過外部訪問和修改,只能通過組件內(nèi)部的this.setState來修改笔诵,修改state屬性會導(dǎo)致組件的重新渲染返吻。

區(qū)別

state是組件自己管理數(shù)據(jù),控制自己的狀態(tài)乎婿,可變测僵;
props是外部傳入的數(shù)據(jù)參數(shù),不可變次酌;
沒有state的叫做無狀態(tài)組件恨课,有state的叫做有狀態(tài)組件舆乔;
多用props,少用state希俩。也就是多寫無狀態(tài)組件纲辽。

2.Object.assign方法

參考:https://github.com/ruanyf/es6tutorial/blob/06fac98bb11b0b1f3fccd396d402e918ae3fc002/docs/object.md

基本用法

Object.assign方法用于對象的合并拖吼,將源對象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對象(target)吊档。

const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

Object.assign方法的第一個參數(shù)是目標(biāo)對象怠硼,后面的參數(shù)都是源對象。

注意香璃,如果目標(biāo)對象與源對象有同名屬性葡秒,或多個源對象有同名屬性,則后面的屬性會覆蓋前面的屬性眯牧。

  1. const target =``{ a:``1, b:``1``};
  2. const source1 =``{ b:``2, c:``2``};
  3. const source2 =``{ c:``3``};
  4. Object.assign(target, source1, source2);
  5. target // {a:1, b:2, c:3}

如果只有一個參數(shù)炸站,Object.assign會直接返回該參數(shù)。

  1. const obj =``{a:``1};
  2. Object.assign(obj)``=== obj // true

注意點

(1)淺拷貝

Object.assign方法實行的是淺拷貝,而不是深拷貝腿堤。也就是說,如果源對象某個屬性的值是對象忌堂,那么目標(biāo)對象拷貝得到的是這個對象的引用酗洒。

  1. const obj1 =``{a:``{b:``1}};
  2. const obj2 =``Object.assign({}, obj1);
  3. obj1.a.b =``2;
  4. obj2.a.b // 2

上面代碼中,源對象obj1的a屬性的值是一個對象棋嘲,Object.assign拷貝得到的是這個對象的引用。這個對象的任何變化痪伦,都會反映到目標(biāo)對象上面雹锣。

(2)同名屬性的替換

對于這種嵌套的對象,一旦遇到同名屬性辉哥,Object.assign的處理方法是替換攒射,而不是添加匆篓。

  1. const target ={ a:{ b:*‘c’, d:*``*‘e’*``*}*``*}*
  2. const source =*{ a:*``*{ b:*``*‘hello’*``*}*``*}*
  3. Object.assign(target, source)
  4. // { a: { b: ‘hello’ } }

上面代碼中,target對象的a屬性被source對象的a屬性整個替換掉了鸦概,而不會得到{ a: { b: ‘hello’, d: ‘e’ } }的結(jié)果窗市。這通常不是開發(fā)者想要的,需要特別小心论熙。

一些函數(shù)庫提供Object.assign的定制版本(比如 Lodash 的_.defaultsDeep方法)摄狱,可以得到深拷貝的合并。

(3)數(shù)組的處理

  1. Object.assign可以用來處理數(shù)組祝谚,但是會把數(shù)組視為對象酣衷。
  2. Object.assign([1,2,3],[4,5])
  3. // [4, 5, 3]

上面代碼中,Object.assign把數(shù)組視為屬性名為 0席爽、1、2 的對象玖像,因此源數(shù)組的 0 號屬性4覆蓋了目標(biāo)數(shù)組的 0 號屬性1炬藤。

(4)取值函數(shù)的處理

Object.assign只能進(jìn)行值的復(fù)制,如果要復(fù)制的值是一個取值函數(shù)上真,那么將求值后再復(fù)制羹膳。

  1. const source ={
  2. get foo(){return1}
  3. };
  4. const target ={};
  5. Object.assign(target, source)
  6. // { foo: 1 }

上面代碼中,source對象的foo屬性是一個取值函數(shù)就珠,Object.assign不會復(fù)制這個取值函數(shù)醒颖,只會拿到值以后,將這個值復(fù)制過去逼侦。
如果該參數(shù)不是對象腰耙,則會先轉(zhuǎn)成對象挺庞,然后返回。

3.ES6拓展運(yùn)算符

參考:http://es6.ruanyifeng.com/#docs/object#對象的拓展運(yùn)算符
擴(kuò)展運(yùn)算符
對象的擴(kuò)展運(yùn)算符(…)用于取出參數(shù)對象的所有可遍歷屬性选侨,拷貝到當(dāng)前對象之中援制。

  1. let z =``{ a:``3, b:``4``};
  2. let n =``{``…z };
  3. n // { a: 3, b: 4 }

這等同于使用Object.assign方法。

  1. let aClone =``{``…a };
  2. // 等同于
  3. let aClone =``Object.assign({}, a);

4.dva connect函數(shù)

參考:
https://dvajs.com/guide/introduce-class.html#connect-%E6%96%B9%E6%B3%95

connect 方法

connect 是一個函數(shù),綁定 State 到 View。

  1. import``{ connect } from ‘dva’;
  2. function mapStateToProps(state)``{
  3. return``{ todos: state.todos };
  4. }
  5. connect(mapStateToProps)(App);

connect 方法返回的也是一個 React 組件掌栅,通常稱為容器組件码泛。因為它是原始 UI 組件的容器,即在外面包了一層 State晌缘。
connect 方法傳入的第一個參數(shù)是 mapStateToProps 函數(shù)痢站,mapStateToProps 函數(shù)會返回一個對象阵难,用于建立 State 到 Props 的映射關(guān)系。

5.dispatch方法

dispatch 方法

dispatch 是一個函數(shù)方法呜叫,用來將 Action 發(fā)送給 State朱庆。

  1. dispatch({
  2. type:``‘click-submit-button’,
  3. payload:``this.form.data
  4. })

dispatch 方法從哪里來?被 connect 的 Component 會自動在 props 中擁有 dispatch 方法傲诵。


前后端傳值示例:

先看一下項目目錄:

image

1.Index——index.js

import dva from ‘dva’;
import ‘./index.less’;
import ‘./todolist.css’;
import createLoading from ‘dva-loading’
import ‘moment/locale/zh-cn’
import {message, notification} from ‘a(chǎn)ntd’
import roleManage from ‘./application/models/roleManager’
import themeConfig from ‘./application/models/themeManager’
// 1\. Initialize
const app = dva({
    onError(e) {
//     notification.error({
//         description: e.message,
//     })
},
});
app.use(createLoading());
// 2\. Plugins
// dbmanager.use({});
// 3\. Model
app.model(require(‘./application/models/userManager’))
….
app.model(require(‘./application/models/todoList’))
// 4\. Router
app.router(require(‘./router’))
// 5\. Start
app.start(‘#root’); 

在index.js中定義了model,dva 提供 app.model 這個對象掰吕,所有的應(yīng)用邏輯都定義在它上面颅痊。

2.Model——userManager.js

說直白點,model就是模型菱属,定義了同步或者異步的操作舰罚,通常是前后端傳值的操作。在model中引入service,通過調(diào)用service的具體方法完成post/get請求等前后端傳值赏陵。
userManager.js如下:

import  as service from “../services/userManager”;
import alert from ‘../../framework/common/alert’
export default {
    namespace: ‘userManager’,
    state: {
        userList:[],
        roleList: [],
        spinning: true,
},
    reducers: {
        save(state, action) {
return {…state, …action.payload};
},
},
    effects: {
 queryUserList({payload}, {call, put}) {
            yield put({type: ‘save’, payload: {spinning: true}})
const {data} = yield call(service.queryUserList)
if (data.code == ‘0’) {
                alert(‘查詢用戶’, data)
} else {
                yield  put({type: ‘save’, payload: {userList: data.payload}})
}
},
addUser({payload}, {call, put}){
const {data} = yield  call(service.addUser, payload)
if (data.code == ‘0’) {
                alert(‘添加人員’, data)
}
            yield  put({type: ‘queryUserList’})
},
update({payload}, {call, put}){
const {data} = yield  call(service.update, payload)
if (data.code == ‘0’) {
                alert(‘修改人員’, data)
}
            yield  put({type: ‘queryUserList’})
},
deleteUser({payload}, {call, put}){
const {data} = yield  call(service.deleteUser, payload)
if (data.code == ‘0’) {
                alert(‘修改人員’, data)
}
            yield  put({type: ‘queryUserList’})
},
 queryAllRole({payload}, {call, put}) {
const {data} = yield call(service.queryAllRole)
if (data.code == ‘0’) {
                alert(‘查詢角色’, data)
}
            yield put({type: ‘save’, payload: {roleList: data.payload}})
},
},
    subscriptions: {
        setup({dispatch, history}) {
},
},
} 

Model 對象的屬性:

namespace: 當(dāng)前 Model 的名稱蝙搔。整個應(yīng)用的 State,由多個小的 Model 的 State 以 namespace 為 key 合成
state: 該 Model 當(dāng)前的狀態(tài)证鸥。數(shù)據(jù)保存在這里勤晚,直接決定了視圖層的輸出
reducers: Action 處理器,處理同步動作鸟蜡,用來算出最新的 State
effects:Action 處理器血淌,處理異步動作
參考:https://dvajs.com/guide/introduce-class.html

3.Service——userManager.js

Service類似Java中的Service,不過這里不用寫接口,直接就是實現(xiàn)類了,在Service中直接調(diào)用方法和后端進(jìn)行數(shù)據(jù)交互癌淮。

import axios from ‘a(chǎn)xios’
export async function queryUserList() {
return axios.get(‘userManager/queryUserList’)
}
export async function addUser(payload) {
return axios.post(‘userManager/addUser’,payload)
}
export async function update(payload) {
return axios.post(‘userManager/update’,payload)
}
export async function deleteUser(payload) {
return axios.post(‘userManager/deleteUser’,payload)
}
export async function queryAllRole() {
return axios.post(‘/role/queryAllRole’)
} 

4.Router——router.js

import React from “react”;
import {Route, Router, IndexRoute} from “dva/router”
import UserManager from ‘./application/views/UserManager/index’
import Todolist from‘./application/views/TodoList’
function RouterConfig({history, app}) {
return (
<Router history={history}>
<Route path=“/“ component={NavLayout}>
<IndexRoute component={UserManager}/>
<Route path=“userManager” component={UserManager}/>
//…
<Route path=“todolist” component={Todolist}/>
</Route>
</Router>
)
}
export default RouterConfig 

router是路由沦补,router.js文件定義了路徑path和對應(yīng)的跳轉(zhuǎn)頁面,類似Java中的Controller夕膀。如:
Route path=”userManager” component={UserManager}/>
component是組件的意思,即相應(yīng)path需要跳轉(zhuǎn)到的頁面魂奥。userManager組件在開頭已經(jīng)通過import引入了:
import UserManager from ‘./application/views/UserManager/index’
當(dāng)訪問http://localhost:8080/userManager 時會自動找到UserManager組件易猫,(位于application/views/UserManager文件夾下的index.js文件)然后將其渲染成頁面。
PS:到這里其實我們知道接下來要來到這個userManager組件所在的頁面了哈蝇。那之前1.2.3.步中的index和model和service有什么用呢攘已?暫時沒有用,因為這些都是為了后面前后臺數(shù)據(jù)交互(傳值)用的吠勘。

5.View——index.js

View顧名思義是視圖層,視圖層就是頁面,在react中即組件,通常一個頁面組件是頂層組件批旺,也就是一個view诵姜,一個頁面組件中通常會包裹其他各種小組件搏熄。截圖如下:

image

里面主要包含各種react周期函數(shù)和自定義的各種方法,最后通過render()來渲染出頁面的html。

以上就是頁面的流通過程,下面結(jié)合具體頁面操作來過一遍前后端傳參過程宵凌。
1.進(jìn)入http://localhost:8080/userManager 頁面:

image

其中import頭部如下:

image

點擊新增按鈕,對應(yīng)View——index.js中render()方法中如下元素:

  1. <Button onClick={()``=>{this.setState({modalDisplay:``“add”})}}
  2. type=“primary” style={{borderRadius:``15, width:``100}}>``新增``</Button>

react中一切皆組件,這個button也是一個組件,里面包含onClick瞎惫、type译株、style屬性。這里的button并不是自定義的組件,而是是引用自antd的開源組件
PS: antd是螞蟻金服開源的基于react的前端UI組件庫具體可以參考官網(wǎng):https://ant.design/components/icon-cn/)
button常用屬性如下:

image

2.onClick觸發(fā)箭頭函數(shù)→this.setState({modalDisplay: “add”})
this.setState是react中的語法乘寒,作用是改變當(dāng)前組件的state伞辛。這時夯缺,看一下整個頁面初始化構(gòu)造器中其實是在state中定義了modalDisplay 的:

constructor(props) {
    super(props)
this.state = {
      userId: window.sessionStorage.getItem(“userId”),
      modalDisplay: “none”,
      selectUser: null,
      modalVisible: false
}
} 

通過給modalDisplay賦值,modalDisplay從null變?yōu)榱恕盿dd”,組件的state改變會觸發(fā)相應(yīng)的元素重新渲染,那么對應(yīng)的就是頁面組件中的Modal組件:

<Modal title={selectUser ? “編輯用戶” : “添加用戶”} visible={modalDisplay === “none” ? false : true}
               onCancel={() => this.handleCancel() }
               cancelText=“關(guān)閉”
               okText=“確定”
               onOk={() => this.editUser()}> 

Modal和button組件一樣竿滨,都是antd組件润文,當(dāng)此組件捕獲到整個state改變后,(modalDisplay從none變?yōu)椤盿dd”),Modal的visible屬性變?yōu)閠rue,故此Modal被渲染了出來,效果是如下彈框:

image

3.前面只是鋪墊曙砂,只是前端頁面的點擊和渲染骏掀,還沒涉及到前后端數(shù)據(jù)交互柱告,從Modal組件上點擊【確定】時笑陈,正式開始前后端傳參過程涵妥。Modal組件上點擊【確定】調(diào)用組件的editUser()方法。

/編輯用戶/
  editUser() {
const {selectUser} = this.state
const {form, dispatch} = this.props
const {validateFields, resetFields} = form
    validateFields((errors, values) => {
if (errors) {
return
}
if (!selectUser) {
        values.userId = this.state.userId
        dispatch({type: ‘userManager/addUser’, payload: values})
        resetFields()
this.setState({modalDisplay: “none”})
} else {
        values.userId = this.state.userId
        dispatch({type: ‘userManager/update’, payload: values})
        resetFields()
this.setState({modalDisplay: “none”, selectUser: null})
}
})
} 

selectUser是頁面組件初始化constructor中定義的state屬性,初始為null窒所。在editUser()中先判斷selectUser,如果為空則執(zhí)行:
dispatch({type: ‘userManager/update’, payload: values})
不為空則執(zhí)行:
dispatch({type: ‘userManager/addUser’, payload: values})
這里帆锋,dispatch是dva中定義的函數(shù),用來將 Action 發(fā)送給 State。Action 是一個普通 javascript對象皮官,它是改變 State 的唯一途徑实辑。一切觸發(fā)state改變的行為都可以叫Action,此處Action即為:{type: ‘userManager/update’, payload: values}
PS:被 connect 的 Component 會自動在 props 中擁有 dispatch 方法。這里頁面組件在開始已經(jīng)做了connect:

  1. @connect(state =>``Object.assign({}, state.userManager,``{loading: state.loading.models.userManager}))

這個connect看起來挺復(fù)雜的讯沈,用到了箭頭函數(shù)婿奔、Object.assign()方法。但是其原理很簡單挤茄,就是綁定state到view冰木。此處即綁定當(dāng)前組件的state到models下的userManager.js(view)
4.此處以dispatch({type: ‘userManager/addUser’, payload: values})為例看一下添加用戶的前后端交互流程。
state改變后觸發(fā)contact綁定過的models中userManager.js中addUser方法:

effects: {
addUser({payload}, {call, put}){
const {data} = yield  call(service.addUser, payload)
if (data.code == ‘0’) {
                alert(‘添加人員’, data)
}
            yield  put({type: ‘queryUserList’})
},
…
} 

在這里call和put方法都是effect內(nèi)部常用的處理函數(shù)歇终。
call:執(zhí)行異步函數(shù),這里通過call方法調(diào)用service來實現(xiàn)向后臺傳值,
put:發(fā)出一個 Action逼龟,類似于 dispatch,這里通過put一個Action:{type: ‘queryUserList’}來改變前臺state狀態(tài)。
5.service.addUse
這里就是前臺頁面向后端傳值的最后一個步驟.

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宜肉,一起剝皮案震驚了整個濱河市翎碑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌日杈,老刑警劉巖达椰,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡檀何,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門栓辜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來藕甩,“玉大人周荐,你說我怎么就攤上這事「抛鳎” “怎么了讯榕?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長济竹。 經(jīng)常有香客問我霎槐,道長,這世上最難降的妖魔是什么栽燕? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮浴讯,結(jié)果婚禮上榆纽,老公的妹妹穿的比我還像新娘。我一直安慰自己奈籽,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布躏升。 她就那樣靜靜地躺著狼忱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佃却。 梳的紋絲不亂的頭發(fā)上窘俺,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天瘤泪,我揣著相機(jī)與錄音,去河邊找鬼均芽。 笑死掀宋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的劲妙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼币呵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了芯义?” 一聲冷哼從身側(cè)響起妻柒,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤举塔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后央渣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡北启,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年暖庄,在試婚紗的時候發(fā)現(xiàn)自己被綠了楼肪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惹悄。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡泣港,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出当纱,到底是詐尸還是另有隱情,我是刑警寧澤晨横,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布箫柳,位于F島的核電站,受9級特大地震影響库糠,放射性物質(zhì)發(fā)生泄漏涮毫。R本人自食惡果不足惜贷屎,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一唉侄、第九天 我趴在偏房一處隱蔽的房頂上張望顷帖。 院中可真熱鬧,春花似錦贬墩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽停做。三九已至,卻和暖如春蛉腌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背舅巷。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工河咽, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留忘蟹,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓寒瓦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親垃你。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

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

  • 個人筆記, 轉(zhuǎn)載請注明轉(zhuǎn)載自 szhshp的第三邊境研究所 Refs and the DOM In the t...
    szhielelp閱讀 1,485評論 0 1
  • 3. JSX JSX是對JavaScript語言的一個擴(kuò)展語法, 用于生產(chǎn)React“元素”凌摄,建議在描述UI的時候...
    pixels閱讀 2,839評論 0 24
  • 前言 組件中的state具體是什么?怎么更改state的數(shù)據(jù)? setState函數(shù)分別接收對象以及函數(shù)有什么區(qū)別...
    itclanCoder閱讀 890評論 0 0
  • 今天來看一下react組件之間是怎么進(jìn)行通訊的锨亏。react推崇的是單向數(shù)據(jù)流,自上而下進(jìn)行數(shù)據(jù)的傳遞浪藻,但是由下而上...
    親親qin閱讀 6,010評論 2 12
  • HTML模版 之后出現(xiàn)的React代碼嵌套入模版中乾翔。 1. Hello world 這段代碼將一個一級標(biāo)題插入到指...
    ryanho84閱讀 6,245評論 0 9