react進(jìn)階漫談

本文主要談自己在react學(xué)習(xí)的過程中總結(jié)出來的一些經(jīng)驗(yàn)和資源枉氮,內(nèi)容邏輯參考了“深入react技術(shù)椗鑫常”一書以及網(wǎng)上的諸多資源,但也并非完全照抄,代碼基本都是自己實(shí)踐,主要為平時(shí)個(gè)人學(xué)習(xí)做一個(gè)總結(jié)和參考乡数。

本文的關(guān)鍵內(nèi)容:樣式處理與css模塊化、組件間通信(非flux架構(gòu))读存、組件抽象、組件性能優(yōu)化以及React 動(dòng)畫五種內(nèi)容。

1.樣式處理與css模塊化

在react出現(xiàn)之前,我們寫樣式一般是將css分離的榆俺,并且用less/sass預(yù)處理器,我個(gè)人在用backbone等MV*框架的時(shí)候就習(xí)慣用less并且用nodejs配置一個(gè)模塊用來編譯less。

但這樣寫會(huì)有一些問題:

  • 命名沖突是一個(gè)很常見的問題谴仙,因此迂求,我們要制定出一套自己的完整命名規(guī)范來,并且要防止和項(xiàng)目中引入的庫出現(xiàn)沖突晃跺。
  • 充分利用優(yōu)先級(jí)是一個(gè)比較好的實(shí)踐,但是這樣寫出的less代碼有點(diǎn)像回調(diào)函數(shù)塔毫玖,雖然我本人并不覺得這有什么不好甚至還比較享受這種編程掀虎,但這的確不利于充分壓縮css代碼。

于是我們引入css modules付枫。

簡單的說烹玉,如果我們配置了css modules的話,那么你在css中寫的類名和你在組件中寫的class = ...都會(huì)被重新編譯成一個(gè)哈希字符串阐滩,這樣我們就不用考慮命名沖突的問題了二打,另外也可以比較自由的在local和global的css變量之間切換(實(shí)際上,這樣的css變量默認(rèn)都是local的掂榔,如果需要global继效,我們需要:global前綴,這樣的話css變量就不會(huì)被轉(zhuǎn)化成特殊的哈希值了)

需要注意的是寫法問題装获,這個(gè)時(shí)候我們就不能在jsx中僅僅用className了瑞信,css module實(shí)際上限制了我們必須要用className={style.title}這樣的寫法,實(shí)際上我在嘗試的時(shí)候因?yàn)檫@個(gè)地方的bug調(diào)試了很久穴豫,而這也在某一種程度上給利用css module進(jìn)行重構(gòu)代碼帶來了一些困難凡简。

關(guān)于css modules的入門介紹,沒錯(cuò)精肃,阮一峰老師寫了一份:http://www.ruanyifeng.com/blog/2016/06/css_modules.html

另外秤涩,有的同學(xué)認(rèn)為css modules并不夠優(yōu)雅,實(shí)際上上文的寫法限定的問題就是一個(gè)麻煩事司抱,所以我們可以用react-css-modules庫筐眷,這個(gè)庫解決了css modules的一些不是很好的問題,因?yàn)樯鲜植⒉浑y状植,這里不詳細(xì)介紹了(可以參考這里以及“深入react技術(shù)椬蔷梗”73頁)

2.組件間通信(非flux架構(gòu))

接下來我們總結(jié)一下react組件間通信的幾種方式,雖然現(xiàn)在有了redux等最佳實(shí)踐津畸,但是很多時(shí)候我們還是需要原生可用的組件通信機(jī)制振定。

父組件向子組件之間

非常常見,通過props機(jī)制傳遞即可肉拓。

子組件向父組件通信
  • 利用回調(diào)函數(shù)后频,回調(diào)函數(shù)本身定義在父組件中,通過props方式傳遞給子組件,在子組件中調(diào)用回調(diào)函數(shù)卑惜。
  • 利用自定義事件機(jī)制膏执,這種方法更通用方便,并且可以簡化API露久,關(guān)于自定義事件機(jī)制的詳細(xì)使用方法我們在接下來展開更米。
跨級(jí)組件通信
  • context機(jī)制。不過這種機(jī)制react并不是特別推薦(不是特別推薦并不代表會(huì)在將來的版本沒有毫痕,只是說明可能會(huì)產(chǎn)生一定的弊端因此要慎用少用)征峦,context機(jī)制需要在上級(jí)組件(可以是父組件的父組件)定義一個(gè)getChildContext函數(shù)如下:
getChildContext(){
    return{
        color:"red",
    }
}
  • 當(dāng)然也可以用事件機(jī)制
沒有層級(jí)關(guān)系的組件通信

這回只能用事件機(jī)制了,雖然我之前分析過別的框架的事件機(jī)制部分都可以單獨(dú)拎出來用消请,但是這里面實(shí)際上有好多方式栏笆。

我首先試了一下js-signals這個(gè)庫,這個(gè)也是React團(tuán)隊(duì)使用的臊泰,用起來也還簡單蛉加,npm install signals之后,我們可以單獨(dú)寫一個(gè)Signal文件:

const signals= require('signals');

var Signal = {
  started : new signals.Signal()
};

我們可以把接收事件的函數(shù)定義在組件B中:

 onStarted(param1, param2){
        alert(param1 + param2);
 }
 constructor(props){
        super(props);
        Signal.started.add(this.onStarted); //add listener
 }

然后在組件A中(注意dispatch的時(shí)候要保證B已經(jīng)被構(gòu)造出來了):

 handlethis () {
     Signal.started.dispatch('foo', 'bar'); //dispatch signal passing custom parameters
 }

 render(){
     return (
         <button onClick={this.handlethis}>發(fā)射事件</button>
     )
 }

其實(shí)還有很多類似的組件缸逃,當(dāng)然我們自己寫一個(gè)功能弱的也不成問題针饥,更多的方式,這篇文章介紹的不錯(cuò)察滑。

3.組件抽象

mixin

mixin是一個(gè)飽受詬病的東西打厘,另外蛋疼的是在ES6的寫法下也不能用,筆者現(xiàn)在寫react的時(shí)候都已經(jīng)不用了贺辰,所以這里進(jìn)行簡單介紹户盯。

我們可以通過在createClass的時(shí)候傳入一個(gè)mixins數(shù)組,這個(gè)數(shù)組里是我們的一些通用的方法:

React.createClass({
    mixins:[method1,method2]
    //...
})

這在ES6的class形式下是不能“直接”使用的饲化。

ES7 decorator 與 mixin

ES7 的 decorator莽鸭,作用就是返回一個(gè)新的 descriptor,并把這個(gè)新返回的 descriptor 應(yīng)用到目標(biāo)方法上吃靠。稍后我們將會(huì)看到硫眨,decorator 并非只能作用到類的方法/屬性上,它還可以作用到類本身巢块。

當(dāng)然礁阁,這個(gè)我只言片語肯定說不明白的,這個(gè)我要推薦淘寶前端團(tuán)隊(duì)的這篇文章族奢。

另外姥闭,core-decorators這個(gè)庫值得關(guān)注,它里面有一個(gè)mixin方法用于實(shí)現(xiàn)mixin越走,原理就是用了ES7 decorator棚品,實(shí)現(xiàn)起來也不是非常復(fù)雜靠欢。

最后,提醒一下ES7 decorator雖然很酷铜跑,但是目前還處于提案階段门怪,雖然借助babel我們已經(jīng)可以體驗(yàn)了,但是距離真正支持還有一段距離

高階組件(HOC)

這是一個(gè)頗值得一提的話題锅纺。

我們應(yīng)該聽說過高階函數(shù)掷空,這種函數(shù)接受函數(shù)作為輸入,或者是輸出一個(gè)函數(shù)囤锉,比如map拣帽、reduce以及sort等函數(shù)。

一個(gè)高階組件只是一個(gè)包裝了另外一個(gè) React 組件的 React 組件嚼锄, 這種包裝通常有兩種方式:

1、屬性代理(Props Proxy):高階組件操控傳遞給 WrappedComponent 的 props蔽豺,
2区丑、反向繼承(Inheritance Inversion):高階組件繼承(extends)WrappedComponent。

高階組件的功能主要有以下幾點(diǎn):

1修陡、代碼復(fù)用沧侥,邏輯抽象,抽離底層準(zhǔn)備(bootstrap)代碼
2魄鸦、渲染劫持

  • 渲染劫持主要通過反向繼承來實(shí)現(xiàn)宴杀,我們可以選擇是否渲染原組件,也可以改變原組件的渲染結(jié)果(注意:我們通過 var elementsTree = super.render()可以拿到原組件的渲染結(jié)果拾因,然后我們可以改變props之后旺罢,通過原生cloneElement方法創(chuàng)建出新的節(jié)點(diǎn)樹)

3、State 抽象和更改

  • 所謂抽象state的目的绢记,就是將原組件作為一個(gè)純粹的展示型組件扁达,分離內(nèi)部狀態(tài),將state交給高階組件來控制蠢熄。比如:我們可以抽象出一個(gè)控制input的高階組件跪解,從而不用在input中來有很多控制state的代碼。

4签孔、Props 更改

  • 我們可以讀取叉讥、增加、編輯饥追、刪除被包裹組件的props

我在這里沒有給出代碼图仓,為了避免文章過于冗長以及和網(wǎng)上其他專題文章大部分重復(fù),我主要是進(jìn)行一些總結(jié)判耕,具體內(nèi)容我這里仍然是推薦一篇文章

4.組件性能優(yōu)化

PureRender

PureRender這個(gè)概念實(shí)際上和純函數(shù)有關(guān)透绩,Pure指的是對(duì)同樣的輸入(對(duì)于react來說就是props和state)總是得到相同的輸出,針對(duì)這個(gè)問題,React有一個(gè)shouldComponentUpdate鉤子帚豪,這個(gè)鉤子默認(rèn)返回true碳竟,用于props或者state改變或者接收到新的值時(shí)候,可以供用戶重寫狸臣,這樣在接受到相同的props的時(shí)候我們就可以防止其重新渲染莹桅。

PureRenderMixin在這個(gè)時(shí)候要派上用場了,這是一個(gè)能夠?qū)崿F(xiàn)上述功能的官方插件烛亦,react是這樣介紹它的:

If your React component's render function renders the same result given the same props and state, you can use this mixin for a performance boost in some cases.

實(shí)際上是通過一個(gè)淺比較來確定是不是該被渲染诈泼,這實(shí)際上是一個(gè)性能上的權(quán)衡和妥協(xié),深比較真的是耗費(fèi)太多(我們在下一節(jié)會(huì)提出一個(gè)更好的解決方案)煤禽。
寫法也比較簡單:

import PureRenderMixin from 'react-addons-pure-render-mixin';
class FooComponent extends React.Component {
  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
  }

  render() {
    return <div className={this.props.className}>foo</div>;
  }
}

我們可以在這里查看更多信息铐达。

Immutable.js

在傳遞數(shù)據(jù)的時(shí)候,我們可以用Immutable Data進(jìn)一步提高性能檬果。

Immutable.js定義了不可變對(duì)象瓮孙,一個(gè)數(shù)據(jù)結(jié)構(gòu)(Map\List\ArraySet)一旦被定義,就不可變了选脊,我們把它如果用于state杭抠,那么每次變化的時(shí)候需要將state整個(gè)重新賦值。

上文提到恳啥,在shouldComponentUpdate使用PureRenderMixin由于性能權(quán)衡我們只能使用淺比較偏灿,但是如果我們用了Immutable.js,我們有更好的方式:直接用=== or is就可以判斷钝的,因?yàn)镮mmutable.js比較的是兩個(gè)對(duì)象的hashCode或者valueOf翁垂,并且內(nèi)部使用了trie數(shù)據(jù)結(jié)構(gòu)(比如字典樹)來存儲(chǔ),因此性能很高扁藕。

另外沮峡,由于Immutable.js中提供的數(shù)據(jù)結(jié)構(gòu)是不可變的,我們不用擔(dān)心js中源對(duì)象跟隨引用對(duì)象的變化而變化的問題亿柑,也不用考慮函數(shù)中所謂的引用賦值邢疙,這給我們的編程帶來了很多方便。

當(dāng)然也有不方便的是Immutable.js的數(shù)據(jù)結(jié)構(gòu)并不能和原生的數(shù)據(jù)結(jié)構(gòu)混用望薄,因此寫法上需要格外注意疟游,關(guān)于更多資料請看這里.

無狀態(tài)組件

生命周期讓react的組件變得功能非常強(qiáng)大并且復(fù)雜,從而難以維護(hù)痕支,而有的時(shí)候我們又要經(jīng)常寫一些自身沒有狀態(tài)颁虐,只從父組件接受props的組件,這種組件可以提高react的渲染性能卧须,也被官方推薦另绩。

const HelloWorld = (props) => <div>{props.name}</div>
ReactDOM.render(<HelloWorld name="HelloWorld" />,App)

簡單儒陨,高效,在有些不需要改變的地方笋籽,比如沒有用戶交互純聲明性質(zhì)的內(nèi)容蹦漠,可以用無狀態(tài)組件。

react的diff算法

我們想要讓效率更高车海,還要注意的一點(diǎn)就是要照顧react的diff算法笛园,react雖然有一個(gè)復(fù)雜度僅為O(N)的diff算法,但是這個(gè)算法也不是萬能的侍芝,我們要想讓react效能最大化研铆,就要去照顧這個(gè)diff算法。

總的說來州叠,這個(gè)diff算法大概有三點(diǎn)實(shí)現(xiàn)概要:

  • 對(duì)兩棵樹進(jìn)行比較棵红,react認(rèn)為,對(duì)節(jié)點(diǎn)的跨層級(jí)操作移動(dòng)較少咧栗,所以只會(huì)對(duì)相同層級(jí)的dom節(jié)點(diǎn)進(jìn)行比較窄赋,即同一個(gè)父節(jié)點(diǎn)下的字節(jié)點(diǎn),當(dāng)發(fā)現(xiàn)節(jié)點(diǎn)已經(jīng)不存在時(shí)楼熄,就會(huì)刪除節(jié)點(diǎn),當(dāng)發(fā)現(xiàn)節(jié)點(diǎn)新增時(shí)候浩峡,就會(huì)插入節(jié)點(diǎn)可岂。
    • 為了迎合這個(gè)策略,我們盡量不要對(duì)dom節(jié)點(diǎn)進(jìn)行跨層級(jí)操作(比如把某一個(gè)字節(jié)點(diǎn)轉(zhuǎn)而掛在到某一個(gè)孫節(jié)點(diǎn)下面)翰灾,因?yàn)檫@樣效率是比較低的缕粹。
  • 對(duì)組件之間進(jìn)行比較:如果是同一個(gè)類型的組件,按照第一條策略進(jìn)一步比較虛擬dom樹纸淮;如果不是平斩,就將該組件判斷為dirty,從而替換所有字節(jié)點(diǎn)咽块;對(duì)于同一類型的組件绘面,有可能其虛擬dom樹沒有發(fā)生變化,如果能夠確切知道這一點(diǎn)侈沪,那么就可以節(jié)省大量diff的操作時(shí)間揭璃,因此,react允許用戶通過shouldComponentUpdate鉤子來判斷組件是否發(fā)生變化亭罪。
    • 為了迎合這個(gè)策略瘦馍,我們可以使用上面提到的PureRender或者Immutable.js。
  • 當(dāng)節(jié)點(diǎn)處于同一個(gè)層級(jí)应役,react提供了插入情组、移動(dòng)燥筷、刪除操作,這里主要指相似節(jié)點(diǎn)院崇,比如<li>標(biāo)簽肆氓,因此react允許開發(fā)者將同一個(gè)層級(jí)的節(jié)點(diǎn)添加唯一key進(jìn)行操作,同一個(gè)key認(rèn)為是相同節(jié)點(diǎn)亚脆。之后react有一套自己的算法規(guī)則做院,對(duì)節(jié)點(diǎn)進(jìn)行移動(dòng)操作以達(dá)到要求(具體可以參考“深入react技術(shù)棧”176頁)濒持。
    • 為了迎合這一規(guī)則键耕,我們要給li標(biāo)簽等添加一個(gè)key(實(shí)際上已經(jīng)被react強(qiáng)制),另外,在開發(fā)過程中盡量減少將最后一個(gè)節(jié)點(diǎn)移動(dòng)到第一個(gè)的情況柑营,因?yàn)檫@個(gè)時(shí)候react要進(jìn)行很多的移動(dòng)操作屈雄。

5.React 動(dòng)畫

緩動(dòng)函數(shù)

對(duì)于各種動(dòng)畫來說,緩動(dòng)體驗(yàn)一般是:linear < ease淡入淡出 < spring彈性動(dòng)畫\cubic bezier貝塞爾曲線官套。

動(dòng)畫的方式有css動(dòng)畫和js動(dòng)畫酒奶,但是很多時(shí)候我們都是一起用的,所以區(qū)分的太詳細(xì)似乎必要性也不大奶赔。

成熟的動(dòng)畫庫

實(shí)際上動(dòng)畫經(jīng)常是筆者比較忽視的一個(gè)方面惋嚎,由于還沒畢業(yè),大多時(shí)候都是自己做小東西站刑,最后動(dòng)畫就成了可有可無的環(huán)節(jié)另伍,另外現(xiàn)在的各種動(dòng)畫庫很多,方便到只需要一個(gè)class绞旅、只寫一行代碼就可以做出相對(duì)過得去的效果摆尝,自己也就疏于探索。

這部分內(nèi)容主要推薦一些成熟的動(dòng)畫庫因悲。

首先是ReactCSSTransitionGroup堕汞,這個(gè)動(dòng)畫庫提供了一些生命周期鉤子,我們可以利用此加動(dòng)畫晃琳,具體學(xué)API的過程相當(dāng)簡單讯检,我相信看懂上面各個(gè)部分的同學(xué)直接按照給出的鏈接肯定能順利學(xué)會(huì)。

還有react-smooth動(dòng)畫庫卫旱,這也是一個(gè)比較有意思的動(dòng)畫庫视哑,寫法類似css的多關(guān)鍵幀動(dòng)畫。并且?guī)追N緩動(dòng)函數(shù)動(dòng)畫這里都能實(shí)現(xiàn)誊涯。

react-motion也是一個(gè)值得推薦的動(dòng)畫庫挡毅,如果想用spring動(dòng)畫這個(gè)似乎是更好的選擇。

另外暴构,不說react跪呈,還有一個(gè)讓我印象深刻不得不提的就是vivus.js這個(gè)svg動(dòng)畫庫段磨,不得不說真是酷斃了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耗绿,一起剝皮案震驚了整個(gè)濱河市苹支,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌误阻,老刑警劉巖债蜜,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異究反,居然都是意外死亡寻定,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門精耐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狼速,“玉大人,你說我怎么就攤上這事卦停∠蚝” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵惊完,是天一觀的道長僵芹。 經(jīng)常有香客問我,道長小槐,這世上最難降的妖魔是什么淮捆? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮本股,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桐腌。我一直安慰自己拄显,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布案站。 她就那樣靜靜地躺著躬审,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蟆盐。 梳的紋絲不亂的頭發(fā)上承边,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音石挂,去河邊找鬼博助。 笑死,一個(gè)胖子當(dāng)著我的面吹牛痹愚,可吹牛的內(nèi)容都是我干的富岳。 我是一名探鬼主播蛔糯,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窖式!你這毒婦竟也來了蚁飒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤萝喘,失蹤者是張志新(化名)和其女友劉穎淮逻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阁簸,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爬早,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了强窖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凸椿。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖翅溺,靈堂內(nèi)的尸體忽然破棺而出脑漫,到底是詐尸還是另有隱情,我是刑警寧澤咙崎,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布优幸,位于F島的核電站,受9級(jí)特大地震影響褪猛,放射性物質(zhì)發(fā)生泄漏网杆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一伊滋、第九天 我趴在偏房一處隱蔽的房頂上張望碳却。 院中可真熱鬧,春花似錦笑旺、人聲如沸昼浦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽关噪。三九已至,卻和暖如春乌妙,著一層夾襖步出監(jiān)牢的瞬間使兔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工藤韵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留虐沥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓泽艘,卻偏偏與公主長得像置蜀,于是被迫代替她去往敵國和親奈搜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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

  • 深入JSX date:20170412筆記原文其實(shí)JSX是React.createElement(componen...
    gaoer1938閱讀 8,069評(píng)論 2 35
  • 自己最近的項(xiàng)目是基于react的盯荤,于是讀了一遍react的文檔馋吗,做了一些記錄(除了REFERENCE部分還沒開始讀...
    潘逸飛閱讀 3,390評(píng)論 1 10
  • react 基本概念解析 react 的組件聲明周期 react 高階組件,context, redux 等高級(jí)...
    南航閱讀 1,069評(píng)論 0 1
  • 謝女且聽詞秋秤,有心話你知: 眼盈盈宏粤、凝睇清眉 好似開嬌橫遠(yuǎn)岫,又中意灼卢、鬢邊絲 一遇目雙垂绍哎,相思付與誰 得閑時(shí)、欲語還...
    趙蓮貴閱讀 408評(píng)論 3 6
  • 開這個(gè)號(hào)的目的就是為了寫寫寫鞋真。 不求閱讀量崇堰,不求打賞,就是想寫東西的時(shí)候?qū)扅c(diǎn)什么涩咖。 不用有所顧及海诲,表達(dá)最真實(shí)的想法...
    麥田328閱讀 114評(píng)論 0 0