I've been through many tutorials and questions on Stack but I can't find a solution. I'm just learning React/redux, trying to build OnClick action. I've got the following error "Maximum call stack size exceeded error"
. I got this because I'm rendering a function that's changing my state infinitely. I'm trying to deal with my <button onClick={DisplayTable(click)}>cool</button>
differently but nothing seems to work.
I also know that my action and I guess my reducers works properly since when I'm dispatching my action trough the console : $r.store.dispatch({type: 'SET_TABLE_DATA'});
, my state is updated properly.
Any advices ?
here is my action :
export const setTableFilter = (click) => {
return {
type: 'SET_TABLE_DATA',
click : click,
};
};
here is my reducer :
const tableFilter = (state = 0, action) => {
if(action.type === 'SET_TABLE_DATA') {
return state + 1;
}
return state;
}
and here is my component :
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;
I also know that I should build my reducer in a way that my state should be updated without any mutation, however I'll keep this for later ! :)
thanks.
The React onClick event handler enables you to call a function and trigger an action when a user clicks an element, such as a button, in your app. Event names are written in camelCase, so the onclick event is written as onClick in a React app. In addition, React event handlers appear inside curly braces.
The mapStateToProps and mapDispatchToProps deals with your Redux store's state and dispatch , respectively. state and dispatch will be supplied to your mapStateToProps or mapDispatchToProps functions as the first argument.
Start by creating a new react app. I’ll be using a package called Redux Toolkit to get the shell of the app set up quickly. If you’d like to do the same run: This creates your React app to use the official template for working with Redux. Then inside your app run: Now you are all setup. For this example, we will be creating a simple counter.
In React, the onClick handler allows you to call a function and perform an action when an element is clicked. onClick is the cornerstone of any React app.
Handling events in React is simple; events are declared in camelCase in a React app. For instance, if you have to define the onclick event, so we take a little different approach and declare onClick event this way in a React application.
When using a Class component, you would see something like this: This is the standard Redux setup, where we use mapStateToProps to get access to properties on the Redux store available to our component as props, and then dispatch actions to our reducer (also available as props) in order to update those properties.
The answer given doesn't really explain why your code was not working, so I thought I'd expand on that.
Your problem is that you are exceeding the function call stack, more commonly known as infinite recursion. The reason this is happening is because you aren't passing a function to the onClick
attribute of your button, but rather invoking a function and passing its return value instead. So the following scenario is happening:
render()
is calledDisplayTable
function is invoked, which dispatches an update to the storerender()
is called againDisplayTable
is invoked again...and so on.
What you'll want to do instead is pass the function to the button's onClick
attribute. So your component should look like this:
const Component = props => {
return (
<div>
<button onClick={props.DisplayTable}>cool</button>
</div>
);
};
In that above code snippet, I removed your click
prop because it doesn't look like you're using it at all (given the code you posted in the OP).
A few tips, not a complete solution since that would not help you learn:
Your action and reducer are looking fine. You are passing the click property which is not used in the reducer. Maybe you will use it in the future but for now it is useless.
A React component function takes props as an argument:
const Comp = props => {
const click = props.click;
// ...
};
mapDispatchToProps
is usually not needed. Use plain objects instead:
connect(state => state.tableFilter, { setTableFilter })(DisplayTable);
You can then access the function from props:
<button onClick={() => props.setTableFilter(click)}>cool</button>
Keep in mind: onClick
takes a function!
Also the state you defined in the reducer has no property called click, instead it is a number (see correct mapStateToProps function above)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With