0

I am new to React. I created a demo application.And I am trying to hide the message on a button click. 1) But the action does not call on button click. 2) And why the console shows as following when console the action inside the reducer.This shows on page reloads. view page

inside reducer
redux.js:30 Object {type: "@@redux/INIT"}
redux.js:31 Object {}
redux.js:29 inside reducer
redux.js:30 Object {type: "@@redux/PROBE_UNKNOWN_ACTION_j.r.h.g.s.q.b.y.b.9"}
redux.js:31 Object {}
redux.js:29 inside reducer
redux.js:30 Object {type: "@@redux/INIT"}
redux.js:31 Object {}

my package.json

{
  "name": "react-redux-data-flow",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-redux": "^5.0.5",
    "redux": "^3.7.0",
    "redux-thunk": "^2.2.0"
  },
  "devDependencies": {
    "react-scripts": "1.0.7"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { initialMessageAction, clickButtonAction } from './redux.js';
import { connect } from 'react-redux';


class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">        
        </div>
        <p className="App-intro">
        react-redux-data-flow
        </p>
             {this.props.message? <div>hi ..<button onClick={ () => this.props.clickButtonAction }>hide message</button></div>: ''}
      </div>
    );
  }
}

// mapStateToProps.........................................................................................................

   const mapStateToProps = (state, ownProperty) => ({ 

    message:state.geod

  });
//...............................................................................................................................


// DispatchStateToProps.........................................................................................................

   const mapDispatchToProps =  { 

    // initialMessageAction,
    clickButtonAction

  }

// connect to Store...............................................................................................................................

  export default connect(
                             mapStateToProps,
                             mapDispatchToProps

                    )(App);

// .....................................................................................................................................................................

redux.js

import React from 'react';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

//actions.js..............................................................................................


export const initialMessageAction = (geod) => ({

                                                    type:'INITIAL_MESSAGE',
                                                    geod,

});

export const clickButtonAction = () =>{    
                                            console.log('inside click button action');
                                            return {

                                                        type:'CLICK_MESSAGE',

                                                   }
};

//.........................................................................................................

//reducer.js.........................................................................................................

 export const geod = (state ={}, action) => {
    console.log('inside reducer');
    console.log(action);
    console.log(state)
    switch(action.type){


        case 'INITIAL_MESSAGE':
               console.log('inside reducer');
              return action.geod;
        case 'CLICK_MESSAGE':
               return [ 
                        ...state, { 
                                        message: ''
                                  }
                      ]
        default:
                return state;
    }

 };
//.........................................................................................................

//reducer.js.........................................................................................................

    export const reducers = combineReducers({ geod, });
//.........................................................................................................

//store.js.........................................................................................................

  // export const store = createStore(reducers,  applyMiddleware(thunk));
//.........................................................................................................

export function configureStore(initialState = {}) {  
  const store = createStore(
    reducers,
    initialState,
    applyMiddleware(thunk)
  )
  return store;
};

export const store = configureStore(); 

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import './index.css';
// Add these imports - Step 1
import { Provider } from 'react-redux';  
import { store } from './redux';
// ReactDOM.render(<App />, document.getElementById('root'));
// registerServiceWorker();

// Wrap existing app in Provider - Step 2
ReactDOM.render(  
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
1
  • The logs you posted are just logs from Redux to let you know which actions are being dispatched. The actions that are logged here are from Redux itself, dispatched when initializing the store. Commented Jun 20, 2017 at 11:25

3 Answers 3

5

Your error is very small. On your line:

<button onClick={() => this.props.clickButtonAction}>...

you say that when the button is clicked, call the function which returns this.props.clickButtonAction. You can fix it in two ways:

<button onClick={this.props.clickButtonAction}>...

or

<button onClick={() => this.props.clickButtonAction()}>...

The first one passes the function you want to call (this.props.clickButtonAction) into the onClick prop. The second one passes a function which, when called, will call this.props.clickButtonAction.

It's better to use the first one since it's shorter and does not create extra unnecessary functions, but the second solution is useful when you want to pass a custom argument (onClick={() => innerFuction(customArgument)}).

Sign up to request clarification or add additional context in comments.

3 Comments

Now, the clickButtonAction action in the reducer called on button click.But on first button click the object returned is {} .And on the second click on button returns object. inside reducer redux.js:30 Object {type: "CLICK_MESSAGE"} redux.js:31 Object {} redux.js:29 inside reducer redux.js:30 Object {type: "CLICK_MESSAGE"} redux.js:31 [Object] but the message and the button still shows
I think you might be misunderstanding how your store behaves because your logging is a bit confusing. Fix the logging or add redux-logger to your store to better see how each action changes the state.
npm install redux-logger done. Now previous state, action and next state can be logging.
2

1) Tiny error in the button event handler assignment

onClick={ () => this.props.clickButtonAction } will simply return the callback and do nothing

onClick={this.props.clickButtonAction} assigns the callback as the event handler

2) They just look like linting warnings

3 Comments

@alenchill I used 'redux-thunk middleware. Does it need for call a reducer from action creator?
@sojan no, you don't need it for basic action-creators like the one you have. redux-thunk makes it possible to dispatch multiple actions in a single call to an action-creator, and is often used when doing async network calls to update the store state multiple times to keep track of whether we (a) are waiting for a response, (b) have received a response or (c) have received an error.
Wasn't me , thank @ArneHugo, but yep you are not actually using thunks anywhere, and you will never manually call a reducer, that is redux's job. For what its worth your issue now looks like your reducer returning a confused state for CLICK_MESSAGE, it should be returning the empty string in order to be assigned into state.geod which is what your component is consuming
0

Just a little note to re-iterate a point mentioned above:

If you want to pass a custom prop to the function, then you need to use this format:

onClick={() => myFunction(myProps)}

Otherwise, if you just call onClick={myFunction(myProps)}, then myFunction will be called upon render of the button, which is unintended.

Found this out after my component kept dispatching an action inside of myFunction upon render!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.