Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how should I build onClick action in my react component + Redux

Tags:

reactjs

redux

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.

like image 615
Simon Breton Avatar asked Jul 25 '16 17:07

Simon Breton


People also ask

Can you add onClick to react component?

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.

What is mapStateToProps and mapDispatchToProps in react Redux?

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.

How to create a counter in react with Redux?

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.

What is onclick handler in react?

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.

How to handle events in react?

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.

How do I use Redux with a class component?

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.


Video Answer


2 Answers

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:

  • React component is mounted to the DOM
  • render() is called
  • The DisplayTable function is invoked, which dispatches an update to the store
  • The store updates, and passes new props to the React component
  • render() is called again
  • DisplayTable 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).

like image 72
Michael Parker Avatar answered Oct 17 '22 09:10

Michael Parker


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)

like image 35
Herku Avatar answered Oct 17 '22 09:10

Herku