+7 votes
by (13.6m points)

Lots of question I came up with while looking at an react native redux example project. Can anyone point me to a document where those advanced syntactic sugar will be explained?

For instance:

import React, { AppRegistry } from 'react-native';

Why is AppRegistry in {}, and what is the functional difference to the import of React and the import of AppRegistry?

What happens with this import-statement:

import * as types from '../actions/actionTypes';

Will they be imported as an array?

Another thing:

  render() {
    const { state, actions } = this.props;
    return (
      <Counter
        counter={state.count}
        {...actions} />
    );
  }

What will be passed to the Counter-Component? and where are the actions-variable came from? it is destructed from this.props, but in the caller nothing will be passed. Also: the spread operator in

<Counter/>

, will this append another arguments as they would passed with comma separated variable names?

Another thing:

export default function counter(state = initialState, action = {}) {
  switch (action.type) {
    case types.INCREMENT:
      return {
        ...state,
        count: state.count + 1
      };

What does the return-statement really return? The spread operator and a property called "count", will they be merged together, if the spread-operator already contains a variable called "count"?

Also, the project contains a simple file called index.js in the reducers folder with the following plain content:

import counter from './counter';

export {
  counter
};

Does it make sense?

I'm asking because this project is named as example application for using redux in react native, but i think it is to completed for learning purposes. And i am not sure, if everything makes sense here on the structure. But my really question is to clarify these syntactic sugar elements i found there

3 Answers

+6 votes
by (13.6m points)

That's a lot of questions; most of them have nothing to do with React/Redux; they're really about EcmaScript 2015/2016/next. Maybe you'd like to re-phrase your question? Anyway, here's my two cents':

Why is AppRegistry in {}, and what is the functional difference to the import of React and the import of AppRegistry?

What happens with this import-statement:

Here's a little explanation about ES2015 imports . Consider two files:

// A.js
export default 1;
export const two = 2;

// B.js
import one from "./A";
import { two } from "./A";
console.log(one); // 1
console.log(two); // 2

This is (roughly) executed like:

// A.js
module.exports = {
    default: 1,
    two: 2
};

// B.js
var one = require("./A").default;
var two = require("./A").two;

You will notice that in ES2015, curly braces can be used in the import statement to denote that you only want to import a specific export, but not the whole module .

If you omit the curly braces, you will only import the default export.

You can also use asterisks to import all exports (that is the default export and all other named exports) into one binding. For example,

import * as everything from "./A";

should more or less be transpiled to:

var everything = require("./A");

Now, everything is an object with bindings to every export as seen above. Thus, everything.default === 1 and everything.two === 2 .

What will be passed to the Counter-Component?

Only state.count and an argument list of all actions .

What does the return-statement really return?

The object

{
    ...state,
    count: state.count + 1
}

contains an object spread property . Assuming state is

{
    a: 1,
    b: 2
}

it will transpile to:

{
    a: 1,
    b: 2,
    count: state.count + 1
}

Also, the project contains a simple file called index.js in the reducers folder with the following plain content […] Does it make sense?

Importing modules just to export them can make sense in projects where the internals shouldn't be imported directly. I haven't had a look at this particular project, so I'm not in the right place to judge whether this makes sense in this project or not; anyway, there's a shorter syntax for that , too:

export { counter } from "./counter";
0 votes
by (13.6m points)

I dont know of we should ask question like that on Stackoverflow, cause mostly it indicates you are still learning both ES6, and React, and you are not asking about a specific issue.

Anyway to get started quickly you will need to understand ES6, and React, and I would recommend to get started here:

Learn ES6 with Babel

React Simplified

P.S: ignore the title from andrew ray blog, his post is really great.

0 votes
by (13.6m points)

brief summary in code form:

// the same:
let { propertyName } = { propertyName: 1, otherPropertyName: 2 };
var propertyName = { propertyName: 1, otherPropertyName: 2}.propertyName;


import * as types from '../actions/actionTypes';
var types = require('../actions/actionTypes');
// where "types" is set to the "exports" object in actionTypes.js


// essentially "spreads" or merges all of state's values into the object
let obj = {
    ...state,
    count: state.count + 1
};
var obj = _.merge( state, {count: state.count + 1 } );  //underscore merge
var obj = Object.assign( state, {count: state.count + 1 } );  //ES6 Object.assign function for merging
// for loop merge objects
var obj = {};
for ( var x in state ) if (state.hasOwnProperty(x)) obj[x] = state[x];
obj.count = state.count + 1;

For CounterComponent , it just merges the actions object into its CounterComponent's props. It's basically same as:

//spread version
CounterComponents({
  counter: state.count,
  ...actions
});
//underscore merge
CounterComponents(_.merge({
  counter: state.count,
}, actions));
//es6 merge
CounterComponents(Object.assign({
  counter: state.count,
}, actions));
...