2017-02-27 112 views
0

我正在查看this article的redux的超級基本實現的示例。我瞭解它,除非派遣使用prevState。首先,這個函數從哪裏獲得prevState?這與計數器需要的實際狀態有什麼關係?它是否隱式地在名爲prevState的狀態中設置了另一個值?我只是很難理解狀態是如何傳遞給dispatch,然後通過prevState反轉的。我認爲這可能是一個函數式編程思想,我還沒有掌握。謝謝你幫助我理解!瞭解Redux |的基本實現prevState如何使用?

import React, { Component } from 'react'; 
 

 
const counter = (state = { value: 0 }, action) => { 
 
    switch (action.type) { 
 
    case 'INCREMENT': 
 
     return { value: state.value + 1 }; 
 
    case 'DECREMENT': 
 
     return { value: state.value - 1 }; 
 
    default: 
 
     return state; 
 
    } 
 
} 
 

 
class Counter extends Component { 
 
    state = counter(undefined, {}); 
 
    
 
    dispatch(action) { 
 
    this.setState(prevState => counter(prevState, action)); 
 
    } 
 

 
    increment =() => { 
 
    this.dispatch({ type: 'INCREMENT' }); 
 
    }; 
 

 
    decrement =() => { 
 
    this.dispatch({ type: 'DECREMENT' }); 
 
    }; 
 
    
 
    render() { 
 
    return (
 
     <div> 
 
     {this.state.value} 
 
     <button onClick={this.increment}>+</button> 
 
     <button onClick={this.decrement}>-</button> 
 
     </div> 
 
    ) 
 
    } 
 
}

回答

3

React.Component.prototype.setState

好反應的setState方法負責prevState這裏 - 終極版,僅僅是明確的。

讓我們來看看如何使用setState。我們有選項...

  1. setState(nextState) - 只是通過下一狀態並作出反應將更新的組件state相應
  2. setState(nextState, callback) - 選擇指定一旦組件進行重新渲染被稱爲回調 - 只要更新了state,React組件就會重新渲染 - 注意:React文檔通常建議使用componentDidUpdate生命週期方法。
  3. setState((prevState, props) => nextState) - 使用方便地綁定prevStateprops標識符的函數調用,以便我們手動更新狀態。據預計,該功能我們提供返回下個狀態

所以,你有這個

this.setState(prevState => counter(prevState, action)); 

如果不是很明顯,你所提供的代碼示例使用#3。因此,第一個參數prevState將由React提供,這是組件的當前的狀態。第二個參數props在這裏沒有使用,所以我們會忽略它(如果相關,你可以使用道具來更新你的狀態)。


什麼是prevState

究竟是什麼prevState?嗯,我們確定它是你的分量,我們在前面的計數器初始化爲

state = counter(undefined, {}); 
// => { value: 0 } 

所以,當我們派遣一個INCREMENT我們會相處的

this.setState(prevState => counter({value: 0}, {type: 'INCREMENT'}) 

東西線的當前狀態,其中情況counter(減速)將返回

{value: 1} 

此返回值是什麼將成爲下一個0123組件的狀態


重複setState

當然,如果我們要再次INCREMENT應用程序,我們必須像

this.setState(prevState => counter({value: 1}, {type: 'INCREMENT'}) 

counter將返回

{value: 2} 

成爲組件

等的下一個狀態..


「哪裏是反應,終極版之間的線?」

要啓動時,陣營特定代碼是import並且延伸ComponentCounter類。

「但是其他代碼是什麼(counter)呢?」

關於REDX的最酷的事情之一是它的狀態虛無 - Redux只存在於此代碼示例中作爲模式。沒有import,它使用reduxreact-redux。 Redux在此處更多地用作redux思想/原理的實現 - 它是圍繞這種單向數據流和可組合減速器的思想構建的。

「什麼是減速機?」

減速器只是一個函數,當應用於狀態和動作時,返回一個新的狀態。

當然,redux庫包含一些有用的實用程序,可以更容易地在應用程序中實現Redux的模式 - 但實際上,它們都是非常簡單的功能。實際上,Redux的創造者Dan Abramov在egghead上有一個真棒(免費)系列,Getting Started with Redux向您展示了Redux如何一件一件地工作。在我看來,它是有史以來創造的最佳編碼視頻系列之一,在的任何話題。

+0

哦有趣,謝謝你。我沒有意識到你有兩個選擇setState - 對象或函數。我只用過這個對象來設置新的狀態。是否可以使用該函數的回調函數,使這4個選項? – Turnipdabeets

+0

嗯,我鏈接到了文檔,並概述了我的答案中可用的** 3 **選項。 'setState'有** 3 **可供選擇;不是2或4. – naomik

+0

好吧,看起來回調只能與文檔中的對象配對。但它沒有給出使用該回調的例子,或者爲什麼你需要回調。 – Turnipdabeets

0

prevState在這種情況下是一個實際的,當前狀態。它沒有及時回溯,它只是返回當前的狀態,這將用於建立一個新的狀態 - 因爲在Redux和React的概念中,狀態爲immutable,這意味着它永遠不會被修改 - 當您發送新的動作和你的reducer處理 - 你正在創建一個全新的對象(狀態)。

0

首先,請注意,類計數器從React的組件類型延伸。因爲它會繼承一堆屬性和方法,其中之一是setState

我們可以從它需要兩個參數的React documentation for setState看到:

setState(nextState, callback) 

但在印刷精美,它說的:「的第一個參數可以是對象(含零個或多個鍵更新)或返回包含要更新的密鑰的對象的狀態和道具函數。「

在這種情況下,我們只傳遞一個參數,所以我們必須使用它,第一個參數是返回要更新的鍵的對象的函數。

如果我們再看看原來的代碼在使用的setState:

this.setState(prevState => counter(prevState, action)); 

這可能是一個比較容易閱讀和理解,如果我們在ES5 JavaScript語法寫了這個:

this.setState(
    function cb(prevstate) { 
    return counter(prevstate, action) 
    }) 

所以在這種情況下,「prevState」是一個匿名函數的參數。從理論上講,它可以被命名爲任何東西,只要你在函數體內使用相同的名稱來引用它,一切都會很好。然而,將它命名爲「prevState」似乎是一個非常標準的事情(這就是React文檔所使用的)。

如果我們把它看作純粹的JavaScript,那麼你傳遞給這個函數的應該是未定義的。

因此,發射增量行動多次應導致你的狀態值始終爲1,因爲計數器功能總是會使用默認值:

state = { value: 0 } 

我想派遣函數看起來應該像這個:

dispatch(action) { 
    this.setState(counter(this.state, action)); 
} 

UPDATE

This link可以EXPL ain it better,但的確如果你使用函數作爲setState的第一個參數,那麼這個函數將把當前狀態作爲它的參數,這就是prevState如何得到它的值。

+0

術語「回調」作爲通用詞來描述傳遞給另一個函數的函數在這裏是非常危險的。大多數人使用「回調」來描述異步回調,在這種情況下,「返回」值被完全丟棄。但在這種情況下,它是*同步*,並且'return'值是絕對必需的。 – naomik

+0

有趣。你寫的最後一部分 - statevalue總是1.如果prevState實際上是當前狀態,那麼不會this.setState(counter(this.state,action));或this.setState(counter(prevState,action));是一樣的嗎?那麼在櫃檯減速機中,價值會不斷增長? – Turnipdabeets

+0

我沒有意識到React會自動用當前狀態「填充」你函數的第一個參數。所以「prevState」不是null,它是當前狀態。它被稱爲「prevState」,因爲您有一個要處理的操作,並將您的狀態轉換爲新的當前狀態。 – Jim