本文简单的说下redux。
首先这有张网页,里面有文字和内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ReactDemo</title>
</head>
<body>
<div id="title"></div>
<div id="content"></div>
<div id="root"></div>
</body>
</html>
现在让这个网页通过状态来显示标题和内容。
let state = {
title:{
color:'red',
text:'标题'
},
content:{
color:'blue',
text:'内容'
}
}
function renderTitle(){
let title = document.querySelector('#title');
title.style.background = state.title.color;
title.innerHTML = state.title.text;
}
function renderContent(){
let content = document.querySelector('#content');
content.style.background = state.content.color;
content.innerHTML = state.content.text;
}
//渲染的方法
function render(){
renderTitle();
renderContent();
}
render();
这有个问题,首先状态不能是全局的,也不应该哪个方法都可以直接更改,这样做很危险,所以需要提供一个更改状态的方法,修改这状态的时候提供一个对象带有type类型的dispath来修改状态。
//先定义好需要干那些事情(常量)宏
const CHANGE_TITLE_COLOR = 'CHANGE_TITLE_COLOR';
const CHANGE_CONTENT_TEXT = 'CHANGE_CONTENT_TEXT';
let state = {
title:{
color:'red',
text:'标题'
},
content:{
color:'blue',
text:'内容'
}
}
//派发时一个将修改的动作提交过来
//参数{type:'',载荷}
function dispatch(action){ //派发的方法,这里要更改的状态
switch(action.type){
case CHANGE_TITLE_COLOR:
state.title.color = action.color;
break;
case CHANGE_CONTENT_TEXT :
state.content.text = action.text;
break;
default:
break;
}
}
function renderTitle(){
let title = document.querySelector('#title');
title.style.background = state.title.color;
title.innerHTML = state.title.text;
}
function renderContent(){
let content = document.querySelector('#content');
content.style.background = state.content.color;
content.innerHTML = state.content.text;
}
//渲染的方法
function render(){
renderTitle();
renderContent();
}
render();
dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
render();
但是这么写state还是能被外人调到,所以就有了Redux里面的store。
//先定义好需要干那些事情(常量)宏
const CHANGE_TITLE_COLOR = 'CHANGE_TITLE_COLOR';
const CHANGE_CONTENT_TEXT = 'CHANGE_CONTENT_TEXT';
function createStore(){
let state = {
title:{
color:'red',
text:'标题'
},
content:{
color:'blue',
text:'内容'
}
}
let getState = () => state;
//派发时一个将修改的动作提交过来
//参数{type:'',载荷}
function dispatch(action){ //派发的方法,这里要更改的状态
switch(action.type){
case CHANGE_TITLE_COLOR:
state.title.color = action.color;
break;
case CHANGE_CONTENT_TEXT :
state.content.text = action.text;
break;
default:
break;
}
}
//将方法暴露给外面使用
return {dispatch,getState}
}
let store = createStore();
function renderTitle(){
let title = document.querySelector('#title');
title.style.background = store.getState().title.color;
title.innerHTML = store.getState().title.text;
}
function renderContent(){
let content = document.querySelector('#content');
content.style.background = store.getState().content.color;
content.innerHTML = store.getState().content.text;
}
//渲染的方法
function render(){
renderTitle();
renderContent();
}
render();
store.dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
render();
dispath写到库里面去多个开发者添加多次还是很恶心的,所以改改代码,将定义状态和规则的部分抽离到外面去。抽离的状态叫initState,抽离的规则叫reducer(也就是所谓的管理员)。
//先定义好需要干那些事情(常量)宏
const CHANGE_TITLE_COLOR = 'CHANGE_TITLE_COLOR';
const CHANGE_CONTENT_TEXT = 'CHANGE_CONTENT_TEXT';
let initState = {
title:{
color:'red',
text:'标题'
},
content:{
color:'blue',
text:'内容'
}
}
//需要两个参数 老的状态和新传递的动作算出新的状态
//如果想获取默认状态就是调用reducer让每一个规则都不匹配将默认值返回
function reducer(state=initState,action){
//reducer是一个纯函数,每次需要返回一个新的状态
switch(action.type){
case CHANGE_TITLE_COLOR:
return {...state,title:{...state.title,color:action.color}};
case CHANGE_CONTENT_TEXT :
return {...state,content:{...state.content,text:action.text}};
default:
return state;
}
}
function createStore(reducer){
let state
let getState = () => state;
//派发时一个将修改的动作提交过来
//参数{type:'',载荷}
function dispatch(action){ //派发的方法,这里要更改的状态
state = reducer(state,action);
}
dispatch({})
//将方法暴露给外面使用
return {dispatch,getState}
}
let store = createStore();
function renderTitle(){
let title = document.querySelector('#title');
title.style.background = store.getState().title.color;
title.innerHTML = store.getState().title.text;
}
function renderContent(){
let content = document.querySelector('#content');
content.style.background = store.getState().content.color;
content.innerHTML = store.getState().content.text;
}
//渲染的方法
function render(){
renderTitle();
renderContent();
}
render();
store.dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
render();
我们发现一个问题,每次dispath之后都得render一下,ok那么我们就整下,其实就是一个发布订阅,每次dispath时都调用订阅号的方法。
//先定义好需要干那些事情(常量)宏
const CHANGE_TITLE_COLOR = 'CHANGE_TITLE_COLOR';
const CHANGE_CONTENT_TEXT = 'CHANGE_CONTENT_TEXT';
let initState = {
title:{
color:'red',
text:'标题'
},
content:{
color:'blue',
text:'内容'
}
}
//需要两个参数 老的状态和新传递的动作算出新的状态
//如果想获取默认状态就是调用reducer让每一个规则都不匹配将默认值返回
function reducer(state=initState,action){
//reducer是一个纯函数,每次需要返回一个新的状态
switch(action.type){
case CHANGE_TITLE_COLOR:
return {...state,title:{...state.title,color:action.color}};
case CHANGE_CONTENT_TEXT :
return {...state,content:{...state.content,text:action.text}};
default:
return state;
}
}
function createStore(reducer){
let state ;
let listeners = [];
let subscirbe = (listener)=>{ //订阅
listeners.push(listener);
return ()=>{
//再次调用时移除监听函数。
listeners = listener.filter(fn => fn !== listener);
}
}
let getState = () => state;
//派发时一个将修改的动作提交过来
//参数{type:'',载荷}
function dispatch(action){ //派发的方法,这里要更改的状态
state = reducer(state,action);
listeners.forEach(listener=>listener());
}
dispatch({})
//将方法暴露给外面使用
return {dispatch,getState,subscirbe}
}
let store = createStore();
function renderTitle(){
let title = document.querySelector('#title');
title.style.background = store.getState().title.color;
title.innerHTML = store.getState().title.text;
}
function renderContent(){
let content = document.querySelector('#content');
content.style.background = store.getState().content.color;
content.innerHTML = store.getState().content.text;
}
//渲染的方法
function render(){
renderTitle();
renderContent();
}
render();
//订阅
store.subscirbe(render)
setTimeout(() => {
store.dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
}, 2000)
//取消订阅
// let unsub = store.subscirbe(render)
// setTimeout(() => {
// unsub();
// store.dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
// }, 2000);
来源:https://www.cnblogs.com/qiaohong/p/9824215.html