2016-07-25 19 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'函数,那么就直接前进。 –

相关问题