Update 2020-05-10: This tutorial is based on old version React JS, not sure if this tutorial is still working.

This article will explain how do I create React JS application with Redux and create-react-app. The goal is to make hello world application with input field.

I assume you already understand basic React JS, Redux, and create-react-app. I am still learning React JS, Redux, and create-react-app, so any feedback is appreciated. I hope this example application makes you easier to learn react redux.

Github repository: https://github.com/kuntoaji/hello-world-input-field

Tutorial

Install create-react-app and create Application with create-react-app.

npm install create-react-app -g
create-react-app hello-world-input-field

Move to project directory, Install redux and react-redux.

cd hello-world-input-field
npm install redux --save
npm install react-redux --save

Create Reducer.

// src/reducers/HelloReducer.js
const HelloReducer = (state, action) => {
  switch (action.type) {
    case 'CHANGE_TEXT':
      console.log('CHANGE_TEXT from HelloReducer');
      return Object.assign({}, state, {text: action.text});
    default:
      console.log('Default value from HelloReducer');
      return state;
  }
}

export default HelloReducer;

Create Action.

// src/actions/HelloAction.js
const HelloAction = (newText) => {
  console.log('from HelloAction.js');
  return {
    type: 'CHANGE_TEXT',
    text: newText
  }
}

export default HelloAction;

Create container component.

import { connect } from 'react-redux';
import App from './App';
import { bindActionCreators } from 'redux';
import HelloAction from './actions/HelloAction';

const mapStateToProps = (state) => {
  console.log('map to state to props, state.text: ' + state.text);
  return {
    text: state.text
  }
}

const mapDispatchToProps = (dispatch) => {
  console.log('map to dispatch to props');
  return bindActionCreators({onChange: HelloAction}, dispatch);
}

const AppContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(App)

export default AppContainer;

Make the Redux store available to the connect().

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import HelloReducer from './reducers/HelloReducer'
import AppContainer from './AppContainer';
import './index.css';

console.log('from index.js');
let store = createStore(HelloReducer, {text: 'Initial value from createStore'});

ReactDOM.render(
  <Provider store={store}>
    <AppContainer />
  </Provider>,
  document.getElementById('root')
);

Edit src/App.js to accept props from Redux.

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  onChangeHandler(event) {
    console.log('from onChangeHandler App.js');
    this.props.onChange(event.target.value);
  }

  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Hello World React JS, Redux, and create-react-app</h2>
        </div>
        <p className="App-intro">
          Hello, {this.props.text}
          {' '}
          <input onChange={this.onChangeHandler.bind(this)}>
          </input>
        </p>
      </div>
    );
  }
}

export default App;

Done. Start server with npm start and open localhost:3000.

Github repository: https://github.com/kuntoaji/hello-world-input-field