
Redux是用于数据状态管理,而react是一个视图层面的库。
如果将两者连接在一起,可以使用官方推荐React-redUX库,其具有高效且灵活的特性。
通过redux将整个应用状态存储到store中,组件可以派发dispatch行为action给store
其他组件通过订阅store中的状态state来更新自身的视图
React 实际上只是 ui 框架,通过 JSX 生成动态 DOM 渲染 UI,没有架构、没有模板、没有设计模式、没有路由、也没有数据管理。所以需要借助其他工具。
redux
npm install redux --save
什么是 redux ?
Redux 是 javascript 状态容器,提供可预测化的状态管理。可以理解为全局数据状态管理工具,用来做组件通信等。
为什么使用 redux ?
当没有使用 redux 时兄弟组件间传值将很麻烦,代码很复杂冗余。使用 redux 定义全局单一的数据 Store,可以自定义 Store 里面存放哪些数据,整个数据结构也是自己清楚的。
redux 工作流 ?

import { createStore } from 'redux' /* * 这是一个 reducer,形式为 (state, action) => state 的纯函数。描述了 action 如何把 state 转变成下一个 state。 * state 的形式取决于你,可以是基本类型、数组、对象、甚至是 Immutable.JS 生成的数据结构。 * 当 state 变化时需要返回全新的对象,而不是修改传入的参数。 */ function counter(state = 0, action) { switch (action.type) { case 'INCremENT': return state + 1 case 'DECRemENT': return state - 1 default: return state; } } // 创建 Redux store 来存放应用的状态 // API 是 { subscribe, dispatch, getState } const store = createStore(counter); // 可以手动订阅更新,也可以事件绑定到视图层。 store.subscribe(() => const sotreState = store.getState() ...... ) // 改变内部 state 惟一方法是 dispatch 一个 action。 store.dispatch({ type: 'INCREMENT' }) store.dispatch({ type: 'DECREMENT' })
redux 三大原则:
单一数据源:整个应用的 state 存放在唯一的一个 store 中。store.getState()
state 是只读的,唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
store.dispatch({
type: 'COMPletE_TODO',
index: 1
})使用纯函数来执行修改(reducer:接收先前的 state 和 action,并返回新的 state)。
function visibilityfilter(state = 'SHOW_ALL', action) { switch (action.type) { case 'SET_VISIBILITY_FILTER': return action.filter default: return state } } function todos(state = [], action) { switch (action.type) { case 'ADD_TODO': return [ ...state, { text: action.text, completed: false } ] case 'COMPLETE_TODO': return state.map((todo, index) => { if (index === action.index) { return Object.assign({}, todo, { completed: true }) } return todo }) default: return state } } import { combineReducers, createStore } from 'redux' const reducer = combineReducers({ visibilityFilter, todos }) const store = createStore(reducer)
React-Redux
npm install react-redux --save
React-Redux 是 Redux 的官方 React 绑定库。它能够使你的 React 组件从 Redux store 中读取数据,并且向 store 分发 actions 以更新数据
React-Redux 将所有组件分成两大类:UI 组件和容器组件。UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。
UI 组件:只负责 UI 的呈现,不带有任何业务逻辑;没有状态(即不使用 this.state 这个变量);所有数据都由参数 this.props 提供;不使用任何 Redux 的 API
容器组件:负责管理数据和业务逻辑,不负责 UI 的呈现;带有内部状态;使用 Redux 的 API。
React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。也就是说,用户负责视觉层,状态管理则是全部交给它。
connect()
import { connect } from 'react-redux'
const Visibletodolist = connect(mapStateToprops, mapDispatchToPRops)(Todolist)上面 VisibleTodoList 便是 UI 组件 TodoList 通过 connect 方法自动生成的容器组件。connect 方法接受两个参数:mapStateToProps 和 mapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将 state 映射到 UI 组件的参数 props,后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。
mapStateToProps()
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}mapStateToProps 是一个函数,它接受 state 作为参数,返回一个对象。这个对象有一个 todos 属性,代表 UI 组件的同名参数,后面的 getVisibleTodos 也是一个函数,可以从 state 算出 todos 的值。mapStateToProps 建立一个从(外部的)state 对象到(UI 组件的)props 对象的映射关系。执行后应该返回一个对象,里面的每一个键值对就是一个映射。
mapDispatchToProps()
mapDispatchToProps 用来建立 UI 组件的参数到 store.dispatch 方法的映射。它定义了哪些用户的操作应该当作 Action,传给 Store。它可以是一个函数,也可以是一个对象。
是函数则会得到 dispatch 和 ownProps(容器组件的 props 对象)两个参数。
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: ownProps.filter,
})
}
}
}是一个对象,它的每个键名也是对应 UI 组件的同名参数,键值应该是一个函数,会被当作 Action creator ,返回的 Action 会由 Redux 自动发出。
const mapDispatchToProps = {
onClick: (filter) => {
type: 'SET_VISIBILITY_FILTER',
filter: filter
};
}<Provider> 组件
connect 方法生成容器组件以后,需要让容器组件拿到 state 对象,才能生成 UI 组件的参数。
React-Redux 提供 Provider 组件,使整个 APP 访问到 Redux store 中的数据 即state。
// src/index.tsx import React from 'react' import Reactdom from 'react-dom' import reportWEBVitals from './reportWebVitals' import { Provider } from 'react-redux' import store from './redux/store' import app from './App' ReactdOM.render( <React.Strictmode> <Provider store={store}> <App /> </Provider> </React.StrictMode>, document.getElementById('root') ) reportWebVitals()






网友评论文明上网理性发言 已有0人参与
发表评论: