English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In this chapter, we will learn how to implement the flux pattern in React applications. We will use the Redux framework. The goal of this chapter is to show the simplest example of each part required to connect Redux and React.
We will install Redux throughcommand promptInstall Redux in the window.
C:\Users\username\Desktop\reactApp>npm install --save react-redux
In this step, we will create folders and files for usactions,reducersandcomponentsAfter completion, this is the appearance of the folder structure.
C:\Users\w3codebox\Desktop\reactApp>mkdir actions C:\Users\w3codebox\Desktop\reactApp>mkdir components C:\Users\w3codebox\Desktop\reactApp>mkdir reducers C:\Users\w3codebox\Desktop\reactApp>type nul > actions/actions.js C:\Users\w3codebox\Desktop\reactApp>type nul > reducers/reducers.js C:\Users\w3codebox\Desktop\reactApp>type nul > components/AddTodo.js C:\Users\w3codebox\Desktop\reactApp>type nul > components/Todo.js C:\Users\w3codebox\Desktop\reactApp>type nul > components/TodoList.js
actions are JavaScript objects that usetypeproperty to notify the data that should be sent to the store. We are definingADD_TODOThe operation to be used to add a new item to the list is. TheaddTodoA function is an action creator that returns our actions andidSet up for each item created.
export const ADD_TODO = 'ADD_TODO' let nextTodoId = 0; export function addTodo(text) { return { type: ADD_TODO, id: nextTodoId++, text }; }
While actions will only trigger changes in the application, reducers will specify these changes. We are using a switch statement to search for ADD_TODO actions. A reducer is a function that needs two parameters (state and action) to calculate and return the updated state.
The first function is used to create a new item, and the second function pushes the item into the list. Finally, we will use the combineReducers helper function, where we can add any new reducers that may be used in the future.
import { combineReducers } from 'redux' import { ADD_TODO } from '../actions/actions function todo(state, action) { switch (action.type) { case ADD_TODO: return { id: action.id, text: action.text, } default: return state } } function todos(state = [], action) { switch (action.type) { case ADD_TODO: return [ ...state, todo(undefined, action) ] default: return state } } const todoApp = combineReducers({ todos ) export default todoApp
The store is where the application state is stored. It is very easy to create a store once you have reducers. We pass the store property to the provider element, which wraps the route components.
import React from 'react' import { render } from 'react'-dom' import { createStore } from 'redux' import { Provider } from 'react'-redux import App from './/App.jsx import todoApp from './/reducers/reducers let store = createStore(todoApp) let rootElement = document.getElementById('app') render( <Provider store={store}> <App /> </Provider>, rootElement )
The App component is the root component of the application. Only the root component should know about Redux. An important part to note is the connect function used to connect the root component App to the store.
This function takes the select function as a parameter. The select function retrieves the state from the store and returns the props (visibleTodos) that we can use in the component.
import React, { Component } from 'react' import { connect } from 'react'-redux import { addTodo } from './/actions/actions import AddTodo from './/components/AddTodo.js import TodoList from './/components/TodoList.js class App extends Component { render() { const { dispatch, visibleTodos } = this.props return ( <div> <AddTodo onAddClick={text => dispatch(addTodo(text))} /> <TodoList todos={{visibleTodos}}/> </div> ) } } function select(state) { return { visibleTodos: state.todos } } export default connect(select)(App);
These components should not know about redux.
import React, { Component, PropTypes } from 'react' export default class AddTodo extends Component { render() { return ( <div> <input type='text' ref='input' /> <button onClick={(e) => this.handleClick(e)}> Add </button> </div> ) } handleClick(e) { const node = this.refs.input const text = node.value.trim() this.props.onAddClick(text) node.value = '' } }
import React, { Component, PropTypes } from 'react' export default class Todo extends Component { render() { return ( <li> {this.props.text} </li> ) } }
import React, { Component, PropTypes } from 'react' import Todo from './Todo.js export default class TodoList extends Component { render() { return ( <ul> {this.props.todos.map(todo => <Todo key = {todo.id} {...todo} /> )} </ul> ) } }
When the application starts, we will be able to add projects to the list.