从0到1学习react(三)

190 阅读1分钟

作者:胡子大哈 原文链接: 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())