共计 5065 个字符,预计需要花费 13 分钟才能阅读完成。
欢迎关注公众号:n 平方如有问题或建议,请后台留言,我会尽力解决你的问题。
简介
Redux 是针对 JavaScript 应用的可预测状态容器。
如果熟悉设计模式之观察者模式理解起来就简单了。就是将你在其他组件中需要用到的数据放到一个容器中,那么组件就可以从其中取放数据的东西就是 redux 的工作。
特性:
可预测性 (predictable): 因为 Redux 用了 reducer 与纯函数(pure function) 的概念,每个新的 state 都会由旧的 state 建来一个全新的 state。因而所有的状态修改都是”可预测的”。
状态容器 (state container): state 是集中在单一个对象树状结构下的单一 store,store 即是应用程序领域(app domain) 的状态集合。
JavaScript 应用: 这说明 Redux 并不是单指设计给 React 用的,它是独立的一个函数库,可通用于各种 JavaScript 应用。
核心概念
action:是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据)传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。
reducer:指定了应用状态的变化如何响应 actions, 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
store:store 就是把 action 和 reducer 联系到一起的对象,store 本质上是一个状态树,保存了所有对象的状态。任何 UI 组件都可以直接从 store 访问特定对象的状态。Store 有以下职责:
维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。
再次强调一下 Redux 应用只有一个单一的 store。
基本原理
这个数据流的位于最中心的设计是一个 AppDispatcher(应用发送器),你可以把它想成是个发送中心,不论来自组件何处的动作都需要经过它来发送。每个 store 会在 AppDispatcher 上注册它自己,提供一个 callback(回调),当有动作 (action) 发生时,AppDispatcher(应用发送器)会用这个回调函数通知 store。
由于每个 Action(动作)只是一个单纯的对象,包含 actionType(动作类型)与数据 (通常称为 payload),我们会另外需要 Action Creator(动作创建器),它们是一些辅助函数,除了创建动作外也会把动作传给 Dispatcher(发送器),也就是调用 Dispatcher(发送器) 中的 dispatch 方法。
Dispatcher(发送器)的用途就是把接收到的 actionType 与数据 (payload),广播给所有注册的 callbacks。它这个设计并非是独创的,这在设计模式中类似于 pub-sub(发布 - 订阅) 系统,Dispatcher 则是类似 Eventbus 的概念。
基本使用
安装
npm install –save react-redux
npm install –save-dev redux-devtools
实例主要是理解观察者模式,以及结合原理图先理解 redux 的 action,reducer,store 基本运作。
import {createStore} from ‘redux’
/**
* This is a reducer, a pure function with (state, action) => state signature.
* It describes how an action transforms the state into the next state.
*
* The shape of the state is up to you: it can be a primitive, an array, an object,
* or even an Immutable.js data structure. The only important part is that you should
* not mutate the state object, but return a new object if the state changes.
*
* In this example, we use a `switch` statement and strings, but you can use a helper that
* follows a different convention (such as function maps) if it makes sense for your
* project.
*/
/**
* 来源:官网:https://github.com/reduxjs/redux
*
* 第一步:定义 reducer
*/
function counter(state = 0, action) {
switch (action.type) {
case ‘INCREMENT’:
return state + 1
case ‘DECREMENT’:
return state – 1
default:
return state
}
}
// Create a Redux store holding the state of your app.
// Its API is {subscribe, dispatch, getState}.
// 第二步:根据 reducer 规则生成 store
let store = createStore(counter)
// You can use subscribe() to update the UI in response to state changes.
// Normally you’d use a view binding library (e.g. React Redux) rather than subscribe() directly.
// However it can also be handy to persist the current state in the localStorage.
// 第三步:定义数据(即 state)变化之后的派发规则
store.subscribe(() => console.log(store.getState()))
store.subscribe(() => console.log(store.getState()))
store.subscribe(() => console.log(store.getState()))
// The only way to mutate the internal state is to dispatch an action.
// The actions can be serialized, logged or stored and later replayed.
// 第四步:触发数据变化
store.dispatch({type: ‘INCREMENT’})
// 1
store.dispatch({type: ‘INCREMENT’})
// 2
store.dispatch({type: ‘DECREMENT’})
// 1
常规使用
一般的文件结构,基本就是 store 目录下
actions 的操作 user.js: 主要包含 user 模块下的 action 操作。
import * as types from ‘../constants/types’
export function loginSuccess(data) {
return {
type: types.LOGOIN_SUCCESS,
payload: data
}
}
export function logOut() {
return {
type: types.LOGOUT
}
}
reducers 的操作 module/user.js: 定义
import * as types from ‘../../constants/types’;
export function user(state = 0,action){
switch(action.type) {
case types.LOGOIN_SUCCESS:
console.log(“user……”+ action.payload);
return state+10;
case types.LOGOUT:
return state – 10;
default:
return state;
}
}
index.js 将所有 reducers 的集合在一起。
import {combineReducers} from ‘redux’
import {user} from ‘./module/user’
const rootReducer = combineReducers({
/* your reducers */
user
})
export default rootReducer
store 的操作
import {createStore} from ‘redux’
import rootReducer from ‘./reducers’
export default function configureStore(initialState) {
const store = createStore(rootReducer,initialState,
window.devToolsExtension ? window.devToolsExtension() : undefined
)
return store
}
组件中的操作(简单)
import React from ‘react’;
import {bindActionCreators} from ‘redux’;
import {connect} from ‘react-redux’;
import ComA from ‘./ComA’
import ComB from ‘./ComB’
import * as userInfoActions from ‘../store/actions/user’
class BodyIndex extends React.Component {
componentDidMount() {
this.props.userInfoActions.loginSuccess({
id:’ 呵呵呵呵 ’,
username: ‘bibibiibibi’
})
}
render() {
return (
<div>
<p>Hello world</p>
<ComA user={this.props.user}/>
<ComB user= {this.props.user} />
</div>
)
}
}
function mapStateToProps(state) {
console.log(“mapStateToProps….”+state);
return {
user: state.user.userInfo
}
}
function mapDispatchToProps(dispatch) {
return {
userInfoActions: bindActionCreators(userInfoActions,dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(BodyIndex)
组件中的操作 (常规) 使用 connect 这样子可以省去 mapDispatchToProps,mapDispatchToProps 的操作。
import React from ‘react’;
import {connect} from ‘react-redux’;
import {addComment} from ‘../store/actions/comment’
@connect(
state => ({comment:state.comments.comment}),
{addComment}
)
class TestCom extends React.Component {
componentDidMount() {
this.props.addComment({
comment: 100
})
}
render() {
console.log(“render….”+this.props.comment);
return (
<div>
<p>TestCom…. {this.props.comment} </p>
</div>
)
}
}
export default TestCom;
总结
最后,如果对 Java、大数据感兴趣请长按二维码关注一波,我会努力带给你们价值。觉得对你哪怕有一丁点帮助的请帮忙点个赞或者转发哦。