React 标榜自己是 MVC 里面 V 的部分,那么 Flux 就相当于添加 M 和 C 的部分。
Flux 是 Facebook 使用的一套前端应用的架构模式。
流程:
view 触发action
action通知dispatcher(派发器)
dispatcher通知仓库修改状态
store仓库修改完状态后,通知页面进行重新渲染
安装:
npm i flux --save
第一步:创建仓库
/src/store/index.js
let state = {
name:'flux name',
age:18
}
export default { state }
第二步:在页面组件中引入仓库,并使用仓库中的数据
import React, {
Component } from 'react'
import store from '../store'
export default class Setting extends Component {
render() {
return (
<div>
<h1>系统设置页面</h1>
<h3>仓库中的name为:{
store.state.name }</h3>
</div>
)
}
}
此时只能从仓库中获取数据
第三步:如果想通过页面发起一个事件,来修改仓库中的数据。
从flux中引出Dispatcher派发器,并注册好派发任务,用来修改数据
/src/store/index.js
import { Dispatcher } from 'flux'
let state = {
name:'flux name',
age:18
}
let dispatcher = new Dispatcher();
dispatcher.register(action=>{
switch(action.type){
case "changeName":
state.name = action.params
break;
default:
break;
}
})
export default { state,dispatcher }
action是一个形参,action.type是自定义的一个属性,用来判断要执行什么样的数据操作
action.params是自定义的一个属性,用来接收数据
此时可以在页面组件中通过dispatcher来派发一个具体的任务,用来修改数据
import React, {
Component } from 'react'
import store from '../store'
import User from './User'
export default class Setting extends Component {
setName(){
//通过派发器来派发一个具体的任务,并告知操作的类型及数据
store.dispatcher.dispatch({
type:'changeName',
params:'hello,flux'
})
}
render() {
return (
<div>
<h1>系统设置页面</h1>
<h3>仓库中的name为:{
store.state.name }</h3>
<button onClick={
()=>this.setName() }>修改</button>
<User />
</div>
)
}
}
此时,仓库中的数据会修改,但是页面中没有变化。
当仓库中的数据变化时,页面重新渲染
/src/store/index.js引入事件监听器
// 引入派发器
import {
Dispatcher } from 'flux'
// 引入事件监听器(仓库数据变化后,页面也跟着重新渲染)
import EventEmitter from 'events'
class State extends EventEmitter{
name = 'flux name'
age = 18
}
let state = new State();
//实例化派发器
const dispatcher = new Dispatcher();
//注册具体的派发任务
dispatcher.register(action=>{
//根据传递的参数来执行不同的数据操作
switch(action.type){
case 'changeName':
state.name = action.params;
break;
case 'changeAge':
state.age = action.params;
break;
default:
break;
}
//触发一个事件
state.emit('change')
})
export default {
state,dispatcher }
在页面组件的挂载完成钩子函数中用来监听仓库中的数据变化
import React, {
Component } from 'react'
import store from '../store'
import User from './User'
export default class Setting extends Component {
setName(){
//通过派发器来派发一个具体的任务,并告知操作的类型及数据
store.dispatcher.dispatch({
type:'changeName',
params:'hello,flux'
})
}
componentDidMount(){
//页面组件挂载完成后
//通过仓库中的事件监听器进行监听,然后重新渲染页面
store.state.on('change',()=>{
this.setState({
})
})
}
render() {
return (
<div>
<h1>系统设置页面</h1>
<h3>仓库中的name为:{
store.state.name }</h3>
<button onClick={
()=>this.setName() }>修改</button>
<User />
</div>
)
}
}
Redux由Dan Abramov在2015年创建的科技术语。是受2014年Facebook的Flux架构以及函数式编程语言Elm启发。很快,Redux因其简单易学体积小在短时间内成为最热门的前端架构。
Redux最主要是用作应用状态的管理。简言之,Redux用一个单独的常量状态树(对象)保存这一整个应用的状态,这个对象不能直接被改变。当一些数据变化了,一个新的对象就会被创建(使用actions和reducers)。
redux核心概念:
actions
store
reducers
redux三个原则:
单一数据源
state是只读的
使用纯函数修改state
(1)安装
npm i redux
(2)基本语法
流程:
引入CreateStore
定义初始状态
定义纯函数
定义仓库
示例代码:
①引入createStore
/src/store/index.js
import { createStore } from 'redux'
②定义初始状态
const initalState = {
name:'小飞',
age:18
}
③定义纯函数
state 上一次修改完成后的状态
action是组件dipatch的动作
reducer一定要返回一个新的state,否则就检测不到state的变化
function reducer( state = initalState,action ){
switch(action.type){
case 'changeName':
return{
...state,
name:action.params
}
case 'changeAge':
return{
...state,
age:action.params
}
default:
return state;//一定要返回
}
}
④创建仓库
const store = createStore(reducer);
export default store;
⑤页面组件使用状态
引入仓库
import store from './store'
使用仓库中的数据
仓库中的name为:{ store.getState().name }
⑥改变状态
changeName(){
store.dispatch({
type:'changeName',
params:'小芳'
});
}
⑦使用订阅者实现数据变化页面就变化
componentDidMount(){
//仓库数据变化,想要重新渲染页面,就添加订阅者
store.subscribe(()=>{
this.setState({
})
})
}