Search code examples
reactjsreduxredux-thunk

Redux-thunk: action creator automatically called


I have reducer:

import sliderInitialConfig from '../fixures';

export default (sliderConfig = sliderInitialConfig, action) => {
    const {type, payload} = action;
    switch(type) {
        case "SELECT_CONFIG":
            console.log(sliderConfig);
            return sliderConfig.filter(item => item.id === payload);

        default:
            return sliderConfig;
    }
}

I have action creator (using redux-thunk)

export const selectConfig = (id) => dispatch => {
  dispatch({type: "SELECT_CONFIG", payload: id})
};

I have a part of JSX code, where I am using AC.

 {
    sliderElements.map(item =>
       <li
       key={item.id}
       className="btn"
       onClick={this.props.selectConfig(item.id)}
       >
       {item.device}
       </li>
  )
 }

So, when I load the project in the browser, this AC automatically called, and instead of array of elements, I received empty array, as here:

{sliderElements: Array(4), fetchUser: ƒ, handleToken: ƒ, submitSurvey: ƒ, scrollMovement: ƒ, …}
sliderElements.js:7 (4) [{…}, {…}, {…}, {…}]0: {id: 1, device: "Apple iMac", image: "/static/media/mac_monitor.931c27aa.svg"}1: {id: 2, device: "Apple Macbook Pro", image: "/static/media/mackbook_pro.c9315d2b.png"}2: {id: 3, device: "MSI GP72VR 7RFX", image: "/static/media/iphone_X.bebbd7bc.jpg"}3: {id: 4, device: "Iphone X", image: "/static/media/msi_laptop.8190feed.jpg"}length: 4__proto__: Array(0)
sliderElements.js:7 [{…}]0: {id: 1, device: "Apple iMac", image: "/static/media/mac_monitor.931c27aa.svg"}length: 1__proto__: Array(0)
sliderElements.js:7 []
sliderElements.js:7 []
BlockFive.js:14 {sliderElements: Array(0), fetchUser: ƒ, handleToken: ƒ, submitSurvey: ƒ, scrollMovement: ƒ, …}

Solution

  •        <li
           key={item.id}
           className="btn"
           onClick={this.props.selectConfig(item.id)}
           >
           {item.device}
           </li>
    

    Here, you are calling the selectConfig function. You want to pass this function to the onClick prop, but not call it. You also want to define the value to be used as it's input. There are 2 main ways to do this;

    1. Curry;

      getSelectConfig(id) => () => this.props.selectConfig(id)
      
      ...
      
      onClick={this.getSelectConfig(item.id)}
      
    2. Binding;

      onClick={this.selectConfig.bind(this, item.id)}