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