2016-07-25 22 views
8

我已經通過了許多關於Stack的教程和問題,但找不到解決方案。我剛剛學習React/redux,嘗試構建OnClick操作。我有以下錯誤"Maximum call stack size exceeded error"。我得到了這個,因爲我正在渲染一個無限改變我的狀態的函數。我試圖處理我的<button onClick={DisplayTable(click)}>cool</button>不同,但似乎沒有任何工作。 我也知道我的行動和我想我的減速器正常工作,因爲當我通過控制檯調度我的動作時:$r.store.dispatch({type: 'SET_TABLE_DATA'});,我的狀態正確更新。我應該如何在我的反應組件中構建onClick動作+ Redux

任何建議?

這裏是我的行動:

export const setTableFilter = (click) => { 
    return { 
    type: 'SET_TABLE_DATA', 
    click : click, 
    }; 
}; 

這裏是我的減速器:

const tableFilter = (state = 0, action) => { 
    if(action.type === 'SET_TABLE_DATA') { 
     return state + 1; 
    } 
     return state; 
    } 

,這裏是我的組件:

const DisplayTable = (click) => { 

     return (
     <div> 
      <button onClick={DisplayTable(click)}>cool</button> 
     </div>) 
    } 


function mapStateToProps(state) { 
    return { 
     click: state.tableFilter.click 
    }; 
}; 


const mapDispachToProps = (dispatch) => { 
    return { 
    DisplayTable: (click) => {dispatch (setTableFilter(click)); 
     }, 
    }; 
}; 

const AppTable = connect(mapStateToProps, mapDispachToProps)(DisplayTable); 

export default AppTable; 

我也知道,我要建立我的減速器以我的狀態應該沒有任何突變的方式更新,但是我會保留這個以備後用! :)

謝謝。

+0

既然你提到你是新的反應,[你可能會發現這個網站很有用](https://egghead.io/lessons/javascript-redux-react-counter-example?course=getting-started-with-reux ) – ODelibalta

+0

我已經完成了這個教程,謝謝。它真的幫助我瞭解什麼是減速器,動作和所有......但是當我試圖自己構建這個東西時,它不起作用... –

回答

6

給出的答案並沒有真正解釋爲什麼代碼爲不工作,所以我想我會擴展。

你的問題是你超出了函數調用棧,通常被稱爲無限循環。發生這種情況的原因是因爲您未將按鈕的onClick屬性傳遞給函數,而是調用函數,而是傳遞其返回值。所以以下情形正在發生的事情:

  • 陣營組件被安裝到DOM
  • render()
  • DisplayTable函數被調用,其中調度更新到店
  • 商店更新,通過新道具的陣營組件
  • render()再次調用
  • DisplayTable再次調用

...等等。

你想要做的是將該功能傳遞給按鈕的onClick屬性。所以,你的組件應該是這樣的:

const Component = props => { 
    return (
     <div> 
      <button onClick={props.DisplayTable}>cool</button> 
     </div> 
    ); 
}; 

在上面的代碼片段中,我刪除了你的click道具,因爲它看起來並不像你使用它在所有(給你在OP發佈的代碼) 。

+0

好的謝謝。你真的架構我的問題(除了我正在學習的事實:))。然而,當應用你的snipper得到這個''不能將undefined或null轉換爲對象'。我想那是因爲我的道具是空的物體? –

+1

我可能不得不看更多的代碼才能知道你到底發生了什麼錯誤。也許你可以在[JSBin](https://jsbin.com/?html,output)中加入一個例子? –

+0

這裏我們去[鏈接](https://jsbin.com/citehi/edit?html,console,output) –

2

少數的竅門,因爲這不是一個完整的解決方案不會幫助你學習:

你的動作和減速正在尋找的罰款。您正在通過點擊屬性,該屬性在縮減器中未使用。也許你會在未來使用它,但現在它是沒用的。

甲陣營分量函數採用道具作爲參數:通常不需要

const Comp = props => { 
    const click = props.click; 
    // ... 
}; 

mapDispatchToProps。使用普通對象,而不是:

connect(state => state.tableFilter, { setTableFilter })(DisplayTable); 

然後,您可以從道具訪問功能:

<button onClick="() => props.setTableFilter(click)>cool</button> 

請記住:onClick需要的功能!

另外你在減速中定義的狀態沒有財產稱爲點擊,相反,它是一個數字(見正確mapStateToProps上述功能)

+2

*有時*不需要。原因是因爲connect的第二個參數可以是一個返回對象的函數,或者是一個對象,每個鍵被假定爲一個動作創建者。如果您使用對象,則無論如何都會將其封裝在調度調用中。兩種方法都很好。 –

+0

好的,謝謝。我會嘗試所有這些,但我已經有了第一個問題,爲什麼通常不需要mapDispatchToProps? (這可能會幫助我理解這件事的目的。) –

+0

在你的情況下,不需要傳遞函數到'connect',因爲你可以傳遞一個引用你的動作創建者的對象。所以你仍然會傳遞道具給你的組件,可以將動作派發給商店,你只是以不同的方式來做。就像我說的那樣,兩者真的沒有區別。如果你更喜歡使用'mapDispatchToProps'函數,那麼就直接前進。 –

相關問題