在本章中,我們將學(xué)習(xí)如何在React應(yīng)用程序中實(shí)現(xiàn)通量模式。我們將使用Redux框架。本章的目標(biāo)是展示連接Redux和React所需的每個(gè)部分的最簡單示例。
我們將通過command prompt窗口安裝Redux 。
C:\Users\username\Desktop\reactApp>npm install --save react-redux
在這一步中,我們將創(chuàng)建文件夾和文件對(duì)于我們actions,reducers和components。完成后,這就是文件夾結(jié)構(gòu)的樣子。
C:\Users\nhooo\Desktop\reactApp>mkdir actions C:\Users\nhooo\Desktop\reactApp>mkdir components C:\Users\nhooo\Desktop\reactApp>mkdir reducers C:\Users\nhooo\Desktop\reactApp>type nul > actions/actions.js C:\Users\nhooo\Desktop\reactApp>type nul > reducers/reducers.js C:\Users\nhooo\Desktop\reactApp>type nul > components/AddTodo.js C:\Users\nhooo\Desktop\reactApp>type nul > components/Todo.js C:\Users\nhooo\Desktop\reactApp>type nul > components/TodoList.js

actions 是JavaScript對(duì)象,它們使用type屬性來通知應(yīng)發(fā)送到商店的數(shù)據(jù)。我們正在定義ADD_TODO將用于將新項(xiàng)目添加到列表中的操作。該addTodo函數(shù)是一個(gè)動(dòng)作創(chuàng)建者,它返回我們的動(dòng)作并id為每個(gè)創(chuàng)建的項(xiàng)目設(shè)置一個(gè)。
export const ADD_TODO = 'ADD_TODO'
let nextTodoId = 0;
export function addTodo(text) {
return {
type: ADD_TODO,
id: nextTodoId++,
text
};
}雖然操作只會(huì)觸發(fā)應(yīng)用程序中的更改,但reducer會(huì)指定這些更改。我們正在使用switch語句搜索ADD_TODO操作。reducer是一個(gè)函數(shù),它需要兩個(gè)參數(shù)(state和action)來計(jì)算并返回更新后的狀態(tài)。
第一個(gè)函數(shù)將用于創(chuàng)建一個(gè)新項(xiàng),而第二個(gè)函數(shù)將該項(xiàng)推送到列表中。最后,我們將使用combineReducers助手函數(shù),在這里我們可以添加將來可能使用的任何新的reducer。
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 todoAppstore是存放應(yīng)用程序狀態(tài)的地方。這是非常容易創(chuàng)建一個(gè)存儲(chǔ)一旦你有reducers。我們將store屬性傳遞給provider元素,provider元素包裝了路由組件。
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
)App 組件是應(yīng)用程序的根組件。只有根組件應(yīng)該知道 redux。需要注意的重要部分是用于將根組件 App 連接到商店的 connect 函數(shù)。
這個(gè)函數(shù)以 select 函數(shù)作為參數(shù)。Select 函數(shù)從存儲(chǔ)中獲取狀態(tài),并返回我們可以在組件中使用的道具(visibleTodos)。
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);這些組件不應(yīng)該知道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>
)
}
}啟動(dòng)應(yīng)用程序時(shí),我們將能夠?qū)㈨?xiàng)目添加到列表中。
