React Js Redux: Reducer

Once you had defined your action ( description action type), and still state is not knowing how to change, so here comes to Reducer

Design Your State Case

first you should define how and what you want to change your state

let’s use the most simple demo : increase +1 in Action

{
  type: 'INCREMENT'
}

So in Reducer, it is actually an function, which take care action had dispatch and handle state, you need to pass 2 parameters,
one is initial state, second is the action object:

function counter(state = 0, action) {
  // return state 
}

then you could handle your state inside:

function counter(state = 0, action) {
 switch (action.type) {
   case 'INCREMENT':
   return state + 1;
   default:
   return state;
 }
}

use switch to handle the difference case of state, here you use Increment which return state + 1,  or return default state

Once more example here:  add to do

First define your action:

// actions/TodoActions
export const ADD_TODO = 'ADD_TODO';
export function addTodo(text)
{
  return{
    type: ADD_TODO,
    text
  }
}

here you define action const, and you create Action Creator to return action type

so that send to reducer to change the state:

// reducers/AppReducers
import {ADD_TODO} from 'actions/TodoActions';
export function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ];
    default:
      return state;
  }
}

As you could see once again function todos is an Reducer, and you inject : initial state and action

Then go ahead to return the states by switch case:

first is ADD_TODO, return your todo text, and not completed

else return the default state

Since Reducer is return the state, so keep it simple, remember follow to avoid:

1. change the parameter

2. add any side effect event, like call API or routing change

3. And since reducer is pure function, then you should not called other not pure functions like Date.now() or Math.random()

And you could put as much reducer you want which could separate different object to change, in this way your code will be more reusable and more easy to debug:

function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case TOGGLE_TODO:
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: !todo.completed
          })
        }
        return todo
      })
    default:
      return state
  }
}

function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return action.filter
    default:
      return state
  }
}

function todoApp(state = {}, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  }
}

And Redux provide an function called combinereducers() which allowed you combien those reducers :

import { combineReducers } from 'redux'

const todoApp = combineReducers({
  visibilityFilter,
  todos
})

export default todoApp

Here it is the Reducer concept, hope this could help you understand the core concept

React Js Redux: Action

As last note we had said the core of Redux are Action, Store, Reducer

So that’s try to memories what’s those 3  relation between

For example you need to add a click event, the process is follow:

1 in reducers file add file button.js and write an event constant :

const click => (state, action) { switch (action.type) { case 'ADD' : return state + 1; case 'REMOVE' : return state - 1; } }

2 in action file add file button.js add a function like click(), this method is send the const and data to reducer

3 in container file import action function and send to Button component event

4 Button component will send to DOM

So this simple button event need to get through 4 folder, sounds really complicated right?

Again please look at this picture:

I will advice to look through again the diagram and draw yourself before continuer

Action

Action is the object of Javascript:

const ADD_TODO = 'ADD_TODO'
{
  type: ADD_TODO,
  text: 'Build my first Redux app'
}

Action must have type attribute, it’s present what type of operation (action), type should be defined as string

repeat:

An action MUST

be a plain JavaScript object.
have a type property.

An action MAY

have an error property.
have a payload property.
have a meta property.

you could see more definition flux from here

how action work:

For example if we need to check todo list has done then be checked, we could use index point to specific todo:

{
  type: TOGGLE_TODO,
  index: 5
}

and we need to filter all todo list and show only the completed list:

{
  type: SET_VISIBILITY_FILTER,
  filter: SHOW_COMPLETED
}

You could add as much actin type object you want, but try to keep more simple

Action Creator

Action creator == the function which create action, in Redux action creator return one action, this propose to make code more easy to test and portability:

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

In redux you could use dispatch to active the action creator:

dispatch(addTodo(text))
dispatch(completeTodo(index))

follow is the sample code:

/*
 * action type
 */

export const ADD_TODO = 'ADD_TODO'
export const TOGGLE_TODO = 'TOGGLE_TODO'
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'

/*
 * 其他常數
 */

export const VisibilityFilters = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_COMPLETED: 'SHOW_COMPLETED',
  SHOW_ACTIVE: 'SHOW_ACTIVE'
}

/*
 * action creator
 */

export function addTodo(text) {
  return { type: ADD_TODO, text }
}

export function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

export function setVisibilityFilter(filter) {
  return { type: SET_VISIBILITY_FILTER, filter }
}

It’s must still confused, if you like to dig more I found this article is great to know the concept

Next :reducer, which  is to change the state

React Js Redux

This is basic my note for learning and understand what exact Redux doing

If you had play with Flux, then yes you had pretty much get 80% concept

If you don’t , like me has no clue about Flux , then we could try to learn the concepts step by step:

Concept:

According to the Auther: Dan Abramov

Redux is a library to range states more easier, less API, but more predictable behaviours, it could be practice logging, hot reloading, time travel and universal application, recording and repeating

If you knew about Flux, it was came from the problem of showing message tab box from Facebook messenger by user read or not read, and mean time show different states in the same time, the core is fix this feature problem by Virtual DOM to make user better experience:
1. Improve data consistancy

2. Point root of a bug

3. More meaning unit test

so this was birth of dispatch and action part:

From view to trigger update data even, action send ddata to dispatcher, and dispatcher send payload to all stores, final View ask Store to get state

Point of Redux:

Make state changes more predictable

Reduc 3 pricipales:
1. Single source of truth ( the only data source from ):
states will all wrapped in one store, where has to dispatch the actions

2. State is read only
you could only change state by action

and action is dispatch by store:

3.  Changes are made with pure functions

pure functions == reducer,  action will send the request to reducer, reducer will received older state and return new state, keep reducer is pure and return value to be predictable, follow has 2 reducer, one is for filter and the other is for todos reducer, then use reducer to create store :

function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)

This part is still abstract? follow has the concept diagram:

Process of Redux:
Look upper  diagram, as you could see,  view == components, as user has some operation to trigger action from view ( components) , store.dispatch need to change event content, pass to store for reducer to return next state, state tree has update, trigger view re-render

Redux ==> compositions of store, actions , reducer

Some points in Redux:

As you look some sample code upper in Reducer , do you notice that all the function return directly argument value ? which means in Redux it only accept Pure function, so if your function has re-calculate method like Math.random() , date now() or mapping etc it will not be allowed cause it has to stay simple, less side-effect ( well, that’s why it is called reducer)

Reducer that calculates the next state tree based on the previous state tree and the action being dispatched :

this is important because once you understand this is the key procedure in Reducer then it will make you easily to start to code

Learn more? this link is good to learn the basic concept by photo application
or by the Auther which has videos to show more

React Js learning dairy part 22

componentDidUpdate

componentDidUpdate is usually used for interacting with things outside of the React environment: browser or APIs

will be called after render instead of before ( compare componentWillUpdate)

this method can be used to perform DOM operations after the data has been updated

componentDidUpdate(prevProps, prevState) {
    if (this.state.scrollTop != prevState.scrollTop) {
      console.log('update scrollTop');
    }
  }

As you could see, the update scrollTop will appear once all render finish in the condition of scrollTop recent value not equal to last scrollTop value

Another example:

componentWillMount() {
    this.intervals = [];
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.state.latestClick < prevState.latestClick) {
      this.endGame();
    }
  }

As componentWillMont rendre before, it will start to count the time

And here use componentDidUpdate to end of Game ( after rendre) if there’s no further click event

Voila

Here is basic concept, I hope I could get more exercise to allowed create some demo live code next time

Next will be the last tutorial (oh yeah,,,,,) of lifeCycle method:

componentWillUnmount

React Js learning dairy part 21

componentWillUpdate

  1. gets called in between shouldComponentUpdate and render
  2. receives two arguments: nextProps and nextState.
  3. to interact with things outside of the React architecture, EX: window size or interacting with an API, animation

example:

componentWillUpdate: function(nextProps, nextState) {
        nextState.events.push("Updating component");
    }

Another example:

componentWillUpdate(nextProps,nextState) { 
if (document.body.style.background != yellow && this.state.highest >= 950*1000) { 
   document.body.style.background = yellow; 
 }
 else if (!this.props.game && nextProps.game) { 
   document.body.style.background = 'white'; 
 } 
} 

here as first inject basic 2 arguments: nextProps and nextState, here you are not allowed to call this.setSate(), only if you need to update state in response to props change, use componentWillReceiveProps() instead

and componentWillUpdate() will not be invoked if shouldComponentUpdate() returns false

 

React Js learning dairy part 20

Updating Lifecycle Methods

For updating, here has some method to use:

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

Here we will introduced those 2 methods first

  • componentWillReceiveProps
  • shouldComponentUpdate

componentWillReceiveProps

  1. CALLED: only if component will receive props
  2. CAPTURE THE LAST VALUE
  3. receives nextProps as an argument

example:

componentWillReceiveProps(nextProps){
    this.setState({user: nextProps.user})
  }

if you write follow code instead:

componentWillReceiveProps(){
    this.setState({user: this.props.user})
  }

Then you will not have new state and just setting user back to its current state

PlayCode here

shouldComponentUpdate

  1. compare lifecycle method
  2. automatically receives two arguments: nextProps and nextState
  3. compare nextProps and nextState to the current this.props and this.state, return boolean

example:

 shouldComponentUpdate(nextProps, nextState) {
    if ((this.props.text == nextProps.text) && 
      (this.state.subtext == nextState.subtext)) {
      alert("Props and state haven't changed, so I'm not gonna update!");
      return false;
    } else {
      alert("Okay fine I will update.")
      return true;
    }
  }

As you could shouldComponentUpdate nextProps and nextState arguments, and compare those 2 value, if the props ans state haven’t changed it return false

Here has the same funtionality called PureRenderMixin
As by experts it is advice to avoid use shouldComponentUpdate as for debugging side since it will not render as return false,

Here has good article for it, if you like to check and deep more

React Js learning dairy part 19

In react it has lots methods for life cycle which allowed you from birth ( pre-mounting) and deatch (unmounting)

through life cycle we could let UI renders, updates, thinks about re-rendering and then disappears

Here we start just the birth part:

  • componentWillMount
  • render
  • componentDidMount

componentWillMount

define:

  1. this life cycle method is not used quiet often
  2. will be called only once, before the initial render
  3. will not be triggered when re-rendering

when to use?

  1. like window resizing or focus change
  2. fetch data
  3. render properly from other API

for example

componentWillMount() {
    let mode;
    if (this.props.age > 70) {
      mode = 'old';
    } else if (this.props.age < 18) {
      mode = 'young';
    } else {
      mode = 'middle';
    }
    this.setState({ mode });
  }

As you could see here has initial the value of mode by props attribute value

Another sample is set alert in componentWillMount , componentDidMount, render, you will see the alert order will be follow:

  1. AND NOW, FOR THE FIRST TIME EVER… FLASHY!!!!”  (componentWillMount)
  2. Flashy is rendering! (render)
  3. YOU JUST WITNESSED THE DEBUT OF… FLASHY!!!!!!!  (componentDidMount)
  4. ON SCREEN: OOH LA LA LOOK AT ME I AM THE FLASHIEST

PlayCode here

componentDidMount

define:

componentDidMount is called after the component is rendered for the first time. This can be used to start an async operation as soon as the component shows up

componentDidMount won’t be called in server rendering

usage:

best place to put calls to fetch data

for example:

componentDidMount() {
    this.UserList();
}

this is used to call AJAX api which define in UserList function

Since componentDIdMount called once after the component is rendered

PlayCode here

React Js learning dairy part 18

Talk about form we need to binding dynamic data which receive information from browser via those DOM elements:  <input><textarea>, and <select>

In React to do this there’s 2 method:

Controlled vs UnControlled

Controlled

in order to update the value, it’s need specify an onChange callback for the input. The event in the callback will have the new suggested value from the input. Then take that new value and put it somewhere in your state, then re-render with the new value

usage:

export class Input extends React.Component {
  constructor(props) {
    super(props);
    this.state = { userInput: '' };
    this.handleUserInput = this.handleUserInput.bind(this);
  }
  handleUserInput(e) {
      this.setState({
        userInput: e.target.value
      });
    }

  render() {
    return (
      <div>
        <input type="text" onChange={this.handleUserInput} value={this.state.userInput} />
        <h1>{this.state.userInput}</h1>
      </div>
    );
  }
}

as mentioned: to change input value with onChange attribute which contain the value by callback function: handleUserInput

each time as user put any value it will call handleUserInput, and render the value

A form element becomes controlled if you set if value via a prop, as followed form elements has a different prop for setting that value:

Element Value property Change callback New value in the callback
<input type="text" /> value="string" onChange event.target.value
<input type="checkbox" /> checked={boolean} onChange event.target.checked
<input type="radio" /> checked={boolean} onChange event.target.checked
<textarea /> value="string" onChange event.target.value
<select /> value="option value" onChange event.target.value

PlayCode here

UnControlled

  • it will have to get that information through props
  • has no memory, cause an uncontrolled component keeps the source of truth in the DOM
  • could be less code if you want to quick & dirty
  • use ref

usage:

class Form extends Component {
  handleSubmitClick = () => {
    const name = this._name.value;
    // do something with `name`
  }

  render() {
    return (
      <div>
        <input type="text" ref={input => this._name = input} />
        <button onClick={this.handleSubmitClick}>Sign up</button>
      </div>
    );
  }
}

Here pass a callback in the ref
PlayCode here

I knew it’s been trick, just remember if you had simple in terms of UI feedback, uncontrolled with refs if fine

also you could deep more this article here which I think it’s better explication

What to use? controlled or unControlled?

feature uncontrolled controlled
one-time value retrieval (e.g. on submit)
validating on submit
instant field validation
conditionally disabling submit button
enforcing input format
several inputs for one piece of data
dynamic inputs

React Js learning dairy part 17

PropTypes

Once app grow, it will difficult to check type as coming the bugs,

React provide library to check types

Usage:

1

import PropTypes from 'prop-types';

2

BestSeller.propTypes = {
  title:  React.PropTypes.string.isRequired,
  author: React.PropTypes.string.isRequired,
  weeksOnList: React.PropTypes.number.isRequired
};

Declare propTypes by your instance of class, as follow types you could use:

array, bool, func, number, object, string; symbol, element, node, instanceOf(yourClassName)

for more detail check doc here

3

<li>
        Title: <span>
          {this.props.title}
        </span><br />

        Author: <span>
          {this.props.author}
        </span><br />

        Weeks: <span>
          {this.props.weeksOnList}
        </span>

here in child class rendre props attribute

4

<BestSeller 
              title="Glory and War Stuff for Dads" 
              author="Sir Eldrich Van Hoorsgaard" 
              weeksOnList={10} />

In parent component called child class with attribute and assign them the value

Notice:

  1. PropTypes is an object ( not a function)
  2. your component class expects to receive, there can be one property on your propTypes object.
  3. Property: React.PropTypes.expected-data-type-goes-here (message: React.PropTypes.string)
  4. You can define default values for your props by assigning to the special defaultProps property:
Greeting.defaultProps = {
  name: 'Stranger'
};

outPut:

Next we will go through to React form

React Js learning dairy part 16

You might see this quiet often in react:

 componentDidMount()

this is called: Component life-cycle in react

this allowed us to update the UI and application state

there’s several life circle method in react, but here we just want to show the basic use like componentDidMount, there’s some crucial issue if user component WillMount method,

But I’m not familiar either so here simple show componentDidMount:

What to use:

This function will be called only once in the whole life-cycle of a given component and it being called the component — and all its sub-components — rendered properly.

usage:

cause side effects (AJAX calls etc.)

demo:

componentDidMount() {
    this.interval = setInterval(this.nextGP, 5000);
  }

this could be most use for setInterval

Before this life cycle you should call constructor to allowed initialise component itself, and binding the class method:

 constructor(props) {
    super(props);

    this.state = { currentGP: 0 };

    this.interval = null;

    this.nextGP = this.nextGP.bind(this);
  }

this bind initial state currentGP value as 0, and interval, also call the binding method to change next image

Remember never use setState in constructor

componentWillUnmount()

here use life cycle componentWillUnmount method to clearInterval

this life cycle use for setTimeout, setInterval, or performs any operations need to close/ remove when no need anymore

Remember never user this.setState in this life cycle method

so as fellow is the whole life cycle:

constructor() —–> componentDidMount() —–>componentWillUnMount()—–>render()—–>create all direct-child component

For more Component Lifecycle logical here has good practice link

outPut:

 

you could play code here

So here we had done some basic react, from next dairy we will go to advanced react part