作者:胡子大哈 原文链接: huziketang.com/books/react…
1. redux原理简单实现
"use strict"
const appState = {
title:{
text:"React 练习",
color:"red"
},
content:{
text:"React 练习内容",
color:'blue'
}
}
function renderApp(appState){
console.log("render App```````")
renderTitle(appState.title);
renderContent(appState.content)
}
function renderTitle(title){
console.log("renderTitle")
const titleDom = document.querySelector("#title");
titleDom.innerHTML = title.text;
titleDom.style.color = title.color;
}
function renderContent(content){
console.log("renderContent");
const contentDom = document.querySelector("#content");
contentDom.innerHTML = content.text;
contentDom.style.color = content.color;
}
// renderApp(appState);
// dispatch({ type: 'UPDATE_TITLE_TEXT', text: '《React.js 小书》' }) // 修改标题文本
// dispatch({ type: 'UPDATE_TITLE_COLOR', color: 'blue' }) // 修改标题颜色
// renderApp(appState)
function stateChanger(state,action){
switch(action.type){
case "UPDATE_TITLE_TEXT":
state.title.text = action.text;
break;
case "UPDATE_TITLE_COLOR":
state.title.color = action.color;
break;
default:
break;
}
}
function createStore(state,stateChanger){
//添加监控
//这个地方用到了观察者模式
/**
*为什么会渲染三次?
*1. 是renderApp直接渲染
*2. 后边两次是dispatch,调用dispatch,dispatch函数里面调用了stateChage与listens数组
* 这个数组是调用subscrib的时候,把renderApp当作参数传入
**/
let listeners = [];
const subscibe = (listener) => listeners.push(listener)
const getState = ()=>state;
const dispatch = (action) => {
stateChanger(state,action);
listeners.forEach((listener) => listener())
}
return {getState,dispatch,subscibe};
}
const store = createStore(appState,stateChanger);
store.subscibe(() => renderApp(store.getState()));
renderApp(store.getState());
store.dispatch({type: 'UPDATE_TITLE_TEXT', text: '《React.js 小书》' });
store.dispatch({ type: 'UPDATE_TITLE_COLOR', color: 'purple' });
这里面学习到了观察者模式,为自己以后开发某些场景的时候提供了一个比较好的构思。
2. 优化
"use strict"
const appState = {
title:{
text:"React 练习",
color:"red"
},
content:{
text:"React 练习内容",
color:'blue'
}
}
function renderApp(newAppState, oldAppState = {}){
if(newAppState === oldAppState) return;
console.log("render App```````")
renderTitle(newAppState.title,oldAppState.title);
renderContent(newAppState.content,oldAppState.content)
}
function renderTitle(newTitle,oldTitle = {}){
if(newTitle === oldTitle) return;
console.log("renderTitle");
const titleDom = document.querySelector("#title");
titleDom.innerHTML = newTitle.text;
titleDom.style.color = newTitle.color;
}
function renderContent(newContent, oldContent = {}){
if(newContent === oldContent) return;
console.log("renderContent");
const contentDom = document.querySelector("#content");
contentDom.innerHTML = newContent.text;
contentDom.style.color = newContent.color;
}
// renderApp(appState);
// dispatch({ type: 'UPDATE_TITLE_TEXT', text: '《React.js 小书》' }) // 修改标题文本
// dispatch({ type: 'UPDATE_TITLE_COLOR', color: 'blue' }) // 修改标题颜色
// renderApp(appState)
function stateChanger(state,action){
switch(action.type){
case "UPDATE_TITLE_TEXT":
return {
...state,
title:{
...state.title,
text:action.text
}
}
case "UPDATE_TITLE_COLOR":
return {
...state,
title:{
...state.title,
color:action.color
}
}
default:
return state;
}
}
function createStore(state,stateChanger){
//添加监控
//这个地方用到了观察者模式
try {
// statements
let listeners = [];
const subscibe = (listener) => listeners.push(listener);
const getState = ()=>state;
const dispatch = (action) => {
state = stateChanger(state,action);
listeners.forEach((listener) => listener());
}
return {getState,dispatch,subscibe};
} catch(e) {
// statements
console.log(e);
}
}
const store = createStore(appState,stateChanger);
let oldAppState = store.getState();
store.subscibe(() => {
const newAppState = store.getState();
renderApp(newAppState,oldAppState);
oldAppState = newAppState;
});
renderApp(store.getState());
store.dispatch({type: 'UPDATE_TITLE_TEXT', text: '《React.js 大书》' });
store.dispatch({ type: 'UPDATE_TITLE_COLOR', color: 'purple' });
// renderApp(store.getState())