It's a predictable state container for JavaScript apps. It helps you write applications that behave consistently, run in different environments.
in Redux, there is a single state object that's responsible for the entire state of your application.
This means if you had a React app with ten components, and each component had its own local state,
the entire state of your app would be defined by a single state object housed in the Redux store
.
The Redux store is the single source of truth when it comes to application state
const reducer = (state = 5) => {
return state;
};
const store = Redux.createStore(reducer);
// define a reduce
const reducer = (state = 5) => state;
// create a store based in reducer
const store = Redux.createStore(reducer);
// get current state from state created before
let currentState = store.getState();
Think of Redux actions as messengers that deliver information about events happening in your app to the Redux store. The store then conducts the business of updating state based on the action that occurred.
The action object ideally have a property called type
to have a better behavior into the Redux store.
const store = Redux.createStore(
(state = { login: false }) => state
);
const loginAction = () => {
return {
type: 'LOGIN'
};
};
store.dispatch(loginAction());
After an action is created and dispatched, the Redux store needs to know how to respond to the action.
This is the job of a reducer
function.
- A
reducer
takesstate
andaction
as arguments, and it always returns a newstate
. - It's a pure function.
- It has no side effect.
- In Redux
state
is read-only, that is, must always return a new copy ofstate
;
const defaultState = {
login: false,
};
const reducer = (state = defaultState, action) => {
if (action.type === 'LOGIN') {
return {
login: true,
};
}
return state;
};
const store = Redux.createStore(reducer);
const loginAction = () => {
return {
type: 'LOGIN',
};
};
Use a JavaScript switch
statement in the reducer
to respond to different action events.
This is a standard pattern in writing Redux reducers.
const defaultState = {
authenticated: false,
};
const authReducer = (state = defaultState, action) => {
switch(action.type) {
case 'LOGIN':
return {
authenticated: true,
};
break;
case 'LOGOUT':
return {
authenticated: false,
};
break;
default:
return state;
break;
}
};
const store = Redux.createStore(authReducer);
const loginUser = () => {
return {
type: 'LOGIN',
};
};
const logoutUser = () => {
return {
type: 'LOGOUT',
};
};
const LOGIN = 'LOGIN';
const LOGOUT = 'LOGOUT';
This allows you to subscribe listener functions to the store, which are called whenever an action is dispatched against the store.
store.subscribe(() => { console.log('do something!') });
Remember the first principle of Redux: all app state is held in a single state object in the store.
Redux provides reducer composition as a solution for a complex state model.
In order to let us combine multiple reducers together, Redux provides the combineReducers()
method.
This method accepts an object as an argument in which you define properties which associate keys will be used by Redux as the name
for the associated piece of state.
const rootReducer = Redux.combineReducers({
count: counterReducer,
auth: authReducer,
});
const ADD_NOTE = 'ADD_NOTE';
const notesReducer = (state = 'Initial State', action) => {
switch(action.type) {
case ADD_NOTE:
return action.text;
break;
default:
return state;
}
};
const addNoteText = (note) => {
return {
type: ADD_NOTE,
text: note,
};
};
const store = Redux.createStore(notesReducer);
store.dispatch(addNoteText('Hello!'));
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
const counterReducer = (state = 0, action) => {
switch(action.type) {
case INCREMENT:
return state + 1;
break;
case DECREMENT:
return state - 1;
break;
default:
return state;
}
}
const incAction = () => {
return {
type: INCREMENT
};
};
const decAction = () => {
return {
type: DECREMENT
};
};
const store = Redux.createStore(counterReducer);
store.dispatch(incAction());
store.dispatch(decAction());