我已经学习了很多关于Stack的教程和问题,但我找不到解决方案。我只是在学习React/redux,尝试构建OnClick操作。我收到以下错误"Maximum call stack size exceeded error"
。我之所以得到这个,是因为我正在渲染一个无限改变我状态的函数。我正在尝试以不同的方式处理我的<button onClick={DisplayTable(click)}>cool</button>
,但似乎什么都不起作用。我也知道我的操作和减速器工作正常,因为当我通过控制台$r.store.dispatch({type: 'SET_TABLE_DATA'});
调度操作时,我的状态会正确更新。
有什么建议吗?
这是我的行动:
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;
我也知道我应该构建我的reducer,使我的状态在没有任何突变的情况下更新,但我会在以后保留它!:)
谢谢。
给出的答案并不能真正解释为什么您的代码不工作,所以我想对此进行扩展。
您的问题是超出了函数调用堆栈,通常称为无限递归。之所以会发生这种情况,是因为您没有将函数传递给按钮的onClick
属性,而是调用函数并传递其返回值。因此,以下情况正在发生:
- React组件安装到DOM
render()
被调用- 调用
DisplayTable
函数,它将更新分派到存储 - 商店更新,并将新道具传递给React组件
render()
被再次调用DisplayTable
再次调用
等等
您要做的是将函数传递给按钮的onClick
属性。所以你的组件应该是这样的:
const Component = props => {
return (
<div>
<button onClick={props.DisplayTable}>cool</button>
</div>
);
};
在上面的代码片段中,我删除了您的click
道具,因为它看起来根本没有使用它(考虑到您在OP中发布的代码)。
一些技巧,不是一个完整的解决方案,因为这对你学习没有帮助
你的动作和减速器看起来不错。您正在传递reducer中未使用的click属性。也许你将来会用它,但现在它没用。
React组件函数以props作为参数:
const Comp = props => {
const click = props.click;
// ...
};
通常不需要CCD_ 11。改为使用普通对象:
connect(state => state.tableFilter, { setTableFilter })(DisplayTable);
然后,您可以从道具访问该功能:
<button onClick={() => props.setTableFilter(click)}>cool</button>
请记住:onClick
需要一个函数!
此外,您在reducer中定义的状态没有名为click的属性,而是一个数字(请参阅上面正确的mapStateToProps函数)