简体   繁体   中英

Default parameters are injected as object in babeljs/reactjs?

My reactjs setup with babeljs is show below

在此处输入图片说明

My action.js

export function onIncrement() {
  return {
    type: 'INCREMENT'
  };
}

export function onDecrement() {
  return {
    type: 'DECREMENT'
  };
}

container/App.js

import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as CounterActions from '../actions';

    class App extends Component {
      render() {
        const { counter, actions } = this.props;
        return (
          <div>
            <p>
              Clicked: {counter} times
            </p>
            <p>
              <button onClick={actions.onIncrement}>
                +
              </button>
            </p>
            <p>
              <button onClick={actions.onDecrement}>
                -
              </button>
            </p>
          </div>
        );
      }
    }

    App.propTypes = {
      counter: PropTypes.number.isRequired,
      actions: PropTypes.object.isRequired
    };

    function mapStateToProps(count) {
      return {
        counter: count
      };
    }

    function mapDispatchToProps(dispatch) {
      return {
        actions: bindActionCreators(CounterActions, dispatch)
      };
    }

    export default connect(
      mapStateToProps,
      mapDispatchToProps
    )(App);

containers/root.js

import React, { Component, PropTypes } from 'react';
import { Provider } from 'react-redux';

import App from './App';

export default class Root extends Component {
  render() {
    const { store } = this.props;
    return (
      <Provider store={store}>
        <App />
      </Provider>
    );
  }
}

Root.propTypes = {
  store: PropTypes.object.isRequired
};

Reducer/index.js

export default function counter(count = 0, action) {
  console.log(count)  // this comes as object {}
  console.log(action) // initially it as { type: '@@INIT'}
  switch (action.type) {
    case 'INCREMENT':
      return count + 1;
    case 'DECREMENT':
      return count - 1;
    default:
      return count;
  }
}

store/configureStore.js

import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
import thunkMiddleware from 'redux-thunk';

import rootReducer from '../reducers';

export default function configureStore(initialState = {}) {
  // thunkMiddleware to handle async actions in redux
  const middlewares = [thunkMiddleware];
  // chrome devtool extension
  let devtool;

  if (NODE_ENV === 'development') {
    // redux-logger to log the redux state events in window.console
    const logger = createLogger({
      duration: true
    });
    middlewares.push(logger);

    // devtools - redux-chrome extension
    devtool = window.devToolsExtension ? window.devToolsExtension() : undefined;
  }
  // store - combines reducers and enchancements to redux using middlewares
  const store = createStore(
    rootReducer,
    initialState,
    devtool,
    applyMiddleware(...middlewares)
  );
  // hot module replacement for only for reducers
  if (module.hot) {
    module.hot.accept('../reducers', () => {
      // default - as es6 to es5 transpile in babel make the module to export as
      // module.export = somemodule.default
      const nextRootReducer = require('../reducers').default;
      store.replaceReducer(nextRootReducer);
    });
  }
  return store;
}

my main.js

import 'babel-polyfill';
import React from 'react';
import { render } from 'react-dom';

import Root from './containers/Root';
import configureStore from './store/configureStore';

const initialState = window.__INITIAL_STATE__;

const store = configureStore(initialState);

render(
  ,
  document.getElementById('root')
);

My Package.json

我的package.json

& i am using webpack for bundling and babel for transpiling.

When i initially run this application on i get this error below,

错误

Further investigate this issue, i found the transpiled code as show below

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = counter;
function counter() {
  var count = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];
  var action = arguments[1];

  console.log(count, "count"); // this comes as object {}
  console.log(action, "action"); // initially it as { type: '@@INIT'}
  switch (action.type) {
    case 'INCREMENT':
      return count + 1;
    case 'DECREMENT':
      return count - 1;
    default:
      return count;
  }
}

My Question is:

  1. Why my defualt parameter is injected as Object {} ?
  2. Is this babel problem ?
  3. Am i doing anything wrong here?

The above code only works, when i change this to below,

export default function counter(count = 0, action) {
  console.log(count , "count")  // this comes as object {}
  console.log(action, "action") // initially it as { type: '@@INIT'}
  switch (action.type) {
    case 'INCREMENT':
      return count + 1;
    case 'DECREMENT':
      return count - 1;
    default:
      return 0;
  }
}

In your mapStateToProps function, you first need to extract count from Redux state like this :

function mapStateToProps(state) {
  return {
    counter: state.count
  };
}

future:

That empty object injection is due to i am setting the initialState to = {} in configureStore.js, i changed that to undefined, it worked like a charm

import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
import thunkMiddleware from 'redux-thunk';

import rootReducer from '../reducers';

export default function configureStore(initialState) {
  // thunkMiddleware to handle async actions in redux
  const middlewares = [thunkMiddleware];
  // chrome devtool extension
  let devtool;

  if (NODE_ENV === 'development') {
    // redux-logger to log the redux state events in window.console
    const logger = createLogger({
      duration: true
    });
    middlewares.push(logger);

    // devtools - redux-chrome extension
    devtool = window.devToolsExtension ? window.devToolsExtension() : undefined;
  }
  // store - combines reducers and enchancements to redux using middlewares
  const store = createStore(
    rootReducer,
    initialState,
    devtool,
    applyMiddleware(...middlewares)
  );
  // hot module replacement for only for reducers
  if (module.hot) {
    module.hot.accept('../reducers', () => {
      // default - as es6 to es5 transpile in babel make the module to export as
      // module.export = somemodule.default
      const nextRootReducer = require('../reducers').default;
      store.replaceReducer(nextRootReducer);
    });
  }
  return store;
}

For more details: https://github.com/reactjs/redux/issues/1502#issuecomment-194151490

Check your configureStore function:

export default function configureStore(initialState = {}) {
  // ...
}

You setting initialState to {} , so if window.__INITIAL_STATE__ is undefined you will get {} as initial state of your reducer. Try to change this to:

export default function configureStore(initialState = 0) {
  // ...
}

There is no problems with babel output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM