翻譯|Thinking Statefully

‌原文:Thinking Statefullyjavascript

熟練掌握React的過程包含了如何解決特定問題的方法轉變.這提醒我,這個學習過程有點像在路上不一樣的方向開車. 第一次感覺這一點是,我真正訪問土耳其和卡斯柯島,他們的車都靠左行駛.在美國咱們是靠右行駛,因此要花很大的力氣重編程. 一出機場就差點完蛋了.java

有意思的是,即便我已經能夠在正常的直道上行駛,可是在不一樣狀況發生時,大腦仍然把他轉換成了舊的習慣.react

轉進停車場?習慣接管了,我開進了錯誤的車道.在停車標誌車左轉?仍是一樣的問題.向右轉?你認爲我已經瞭解了一切,可是對於個人大腦,徹底沒這回事.git

我講這個故事是由於在學習React的時候,個人經歷是相似的.我想其餘人也有這樣的經歷.github

傳遞props到組件(最好把組件當作是函數),大腦也已習慣了. 看起來和HTML的工做差很少.編程

在簡單實例中,往下傳遞數據,向上傳遞事件也很好理解.這就是回掉模式,在其餘的地方也很常見.向按鈕組件傳遞一個onClick handler是至關普通.redux

可是若是須要Modal對話框.或者是提示Badge,要怎麼操做?亦或者根據事件響應來對一個Icon進行動畫操做?能夠看到,這些都是命令式的,"事件驅動"的內容在聲明式和狀態時的React世界顯得很不天然.數組

怎麼開發"狀態式"或者是"聲明式"的思考

若是你有jQuery,Angular的經驗或者其餘框架的以經驗,須要調用函數執行任務("過程式編程"),在React的領域裏爲了更爲有效的工做就須要調整思惟模型.從實踐中能夠很快的完成這個轉變-只須要給大腦一些新的實例或者"模式".框架

這裏是一些實例函數

打開/關閉一個Accordion組件(手風琴組件)

舊有辦法: 點擊toggle按鈕調用toggle函數,從而打開或者關閉accordion.Accordion組件知道該怎麼關閉或打開. state方法: Accordion要麼是"open"狀態,要麼是"close"狀態. 這個信息咱們做爲一個標記(flag)存儲在Accordion組件的父組件state上(不在Accordion上存儲).以名爲isOpen的prop形式傳遞state信息,Accordion依據prop來進行渲染. 當isOpentrue時,渲染爲打開,反之就關閉.

<Accordion isOpen={true}/>
// or
<Accordion isOpen={false}/>
複製代碼

這個實例相對簡單.但願不要有什麼認知負擔. 最大的挑戰是以聲明式的React方法處理,打開/關閉的state是存儲在Accordion組件以外,並以prop的形式傳遞的.

打開,關閉一個Dialog

‌舊有辦法: 點擊按鈕打開modal,點擊按鈕關閉. state方法: Modal是開仍是閉是一個狀態,"open","state"二者居其一.因此state是"open",咱們就渲染組件.若是是"close",就不作渲染.此外,能夠給Modal傳遞onClose回調函數-經過這種方法,Modal組件的父組件決定了用戶點擊按鈕時應該幹什麼

{this.state.isModalOpen && <Modal onClose={this.handleClose}/>} 複製代碼

詳細內容請看Modal Dialogs in React

提醒組件

‌舊有辦法: 當一個事件發生時(例如一個錯誤),調用提示庫的組件來顯示popup,例如toast.error("Oh,no!")

state方法: 把提示做爲一個state.有0個或者1個,或多個提示,保存在消息數組中. 在根組件處安置提醒組件. 傳遞state用於顯示.你能夠用不一樣的方式來管理消息數組:

  • 若是使用Redux,保存在store中,Dispatch actions來添加消息
  • 若是不使用Redux,能夠保存在根組件的state中,或者是一個單例對象(整個應用中只實例化一次的對象)中.而後就能夠傳遞向組件傳遞addNotificationprop,或者導入能夠添加到全局單例對象的函數.

在應用中,你可使用軟件包來完成任務,例如react-redux-toastr.可是概念很簡單,因此能夠根據你的需求本身編寫.

用動畫顯示改變

假設你有一個有數字的badge用於顯示登陸的用戶,組件從prop獲取這個數字.可是若是你想在組件數字變化時有點動效,怎麼處理?

‌老辦法: 可使用jQuery來toggle(切換)一個執行動畫的類([^譯註:CSS的類]),或者直接用jQuery操控要執行動畫的元素. state方法: 你能夠在props改變時經過componentWillReceiveProps聲明周期函數比較新舊值來響應變化.若是改變了,能夠把"animating" state設置爲true.接着執行render,當"animating"爲trur時,添加一個執行動畫的CSS類.爲false時,不添加類.這裏是代碼:

componentWillReceiveProps(nextProps) {
if(this.props.counter !== nextProps.counter) {
  // Set animating to true right now. When that state change finishes,
  // set a timer to set animating false 200ms later.
  this.setState({ animating: true }, () => {
    setTimeout(() => {
      this.setState({ animating: false });
    }, 200);
  });
}
}

render() {
const animatingClass = this.state.animating ? 'animating' : '';
return (
  <div className={`badge ${animatingClass}`}> {this.props.counter} </div>
);
}
複製代碼

完成

相關文章
相關標籤/搜索