React makes it painless to create interactive UIs.
Component based.
// book.js import React from "react"; class Book extends React.Component { render() { return ( <h1>{ this.props.title }</h1> ); } } export default Book;
// book_list.js import React from "react"; class BookList extends React.Component { render() { return ( { this.props.books.map((book) => { <Book title={ book.title } /> }) } ); } } export default BookList;
// book_list.js import React from "react"; class BookList extends React.Component { constructor() { super(); this.state = { books: [{ id: 1, title: "Awesome book" }, { id: 2, title: "Programming JS" }] }; } render() { return ( { this.state.books.map((book) => { <Book id={ book.id } title={ book.title } /> }) } ); } } export default BookList;
- Store - single application state
- Actions - describe what happened in your application
- Reducers - describe how to change the state of your application
- Single Source of Truth
- State of the whole application is stored in a single object
- State Is Read-Only
- The only way to change the state is to dispatch actions
- No manual mutations of state
- All changes are centralised
- Changes happen one-by-one (no race conditions)
- Changes are made with pure functions
- Reducers must be pure functions
- Splitting reducers (each reducer handles one part of the state)
Actions are plain JS objects. Each action must have a type
property.
{ type: 'HOLD_WORKSHOP', subject: 'Redux' }
Action creators are functions that return actions.
const holdWorkshop = subject => { return { type: 'HOLD_WORKSHOP', subject }; };
Actions are dispatched using the store.
store.dispatch(action); store.dispatch(holdWorkshop);
Reducers are pure functions that return new application state based on dispatched action.
(prevState, action) => newState
const reducer = (state, action) => { switch(action.type) { case TYPE1: return newState1; case TYPE2: return newState2; default: return state }; };
- Holds whole application state
- Allows access to state via
getState
- Allows changing state via
dispatch(action)
UNIDIRECTIONAL DATA FLOW
- Dispatch action
- Store calls reducers to calculate new state
- Store saves calculated state
- Listeners get notified to update their data via
getState
- Making API requests in components and dispatching actions when response is returned (bad)
- Using middlewares (good)
Using Thunk
middlewares:
- put all asynchronous code in action
- action creator returns a function
- middlewares executes code of that function when action is dispatched
- dispatch normal actions based on response of asynchronous action