把以前學習redux的手寫學習筆記分享出來一下,方便你們理解redux思想,畢竟前端工程師裏面都說,前端
這個是將redux思想的一個拆分, 將 redux 拆分紅 5 部分,最終拼成一個react redux,react
有了redux以後 state再也不是誰均可以任意調用setState修改的數據了,json
<div id="title"></div>
<div id="contents"></div>
<script>
// 渲染模塊
function render() {
document.getElementById('title').innerHTML = state.title;
document.getElementById('contents').innerHTML = state.content;
}
//數據模塊
var state = {
title: '新的標題',
content: '新的內容'
}
//初次渲染執行
render();
//更改數據模塊 ** 更改後觸發數據渲染
function setState(newState) {
this.state = {
...state,
...newState
}
render()
}
</script>
複製代碼
<script>
// 管理模塊, 想要觸發數據改變請執行這個函數, 而且要給指定的type, 不然不執行setState
var dispatch = function (action) {
switch (action.type) {
case 'CHANGE_TITLE': // 傳過來的type正確才能setState
setState({
title: action.newTitle
})
break;
default:
break;
}
}
//修改數據調用dispatch函數, 只有裏面的json的type通過了dispatch檢測才能執行相應的setState
dispatch(
{
type: 'CHANGE_TITLE',
newTitle: '我是通過dispatch函數容許修改後的新標題'
}
)
</script>
複製代碼
<div id="title"></div>
<div id="contents"></div>
<script>
function render() {
document.getElementById('title').innerHTML = state.title;
document.getElementById('contents').innerHTML = state.content;
}
var state = {
title: '新的標題',
content: '新的內容'
}
render()
複製代碼
var dispatch = function (action) {
switch (action.type) {
case 'CHANGE_TITLE':
state = {
...state,
title:action.newTitle
}
break;
default:
break;
}
listeners.forEach(e=>e()) //依次執行數組中訂閱的事件
}
var listeners = []; //這個數組放setState以後執行的事件,
var subscribe = function(listener){ //用subscriber函數把事件push到事件數組中
listeners.push(listener)
}
subscribe(render) // 數組中放入render函數
dispatch(
{
type: 'CHANGE_TITLE',
newTitle: '我是通過dispatch函數容許修改後的新標題'
}
)
</script>
</body>
複製代碼
div id="title"></div>
<div id="contents"></div>
<script>
//渲染函數
function render(state) {
document.getElementById('title').innerHTML = state.title;
document.getElementById('contents').innerHTML = state.content;
}
//store 核心部分
var createStore = function () {
//state數據
var state = {
title: '這是一個標題',
content: '這是一段內容'
}
//執行函數倉庫
var listeners = [];
//獲取state數據
var getState = function () {
return state;
}
//dispatch監控 type是否合法,合法才觸發setState函數
var dispatch = function (action) {
switch (action.type) {
case 'CHANGE_TITLE':
state = {
...state,
title: action.newTitle
}
break;
default:
break;
}
listeners.forEach(e => e())
}
//事件訂閱函數
var subscribe = function (listener) {
listeners.push(listener)
}
// 暴露調用接口
return {
dispatch,
subscribe,
getState
}
}
//調用部分
//建立實例化對象
var store = createStore();
//解構獲取三個接口函數
var { subscribe, dispatch, getState } = store;
//訂閱事件
subscribe(() => render(getState()));
//請求dispatch改變狀態
dispatch(
{
type: 'CHANGE_TITLE',
newTitle: '我是通過dispatch函數容許修改後的新標題'
}
)
render(getState())
</script>
複製代碼
<div id="title"></div>
<div id="contents"></div>
<script>
//store 核心部分
var createStore = function () {
// 將state設置爲 null;
var state = null
var listeners = [];
var dispatch = function (action) {
//調用dispatch時, 執行appReducer作判斷
state = appReducer(state, action);
listeners.forEach(e => e());
}
//調用dispatch初始化state,獲取appReducer中的默認state。
dispatch({})
var subscribe = function (listener) {
listeners.push(listener)
}
var getState = function () {
return state;
}
//暴露接口
return {
dispatch,
subscribe,
getState
}
}
var appReducer = function (state, action) {
//初始化store中的state
//由於state初始值爲null
if (!state) {
return {
title: '這是一個標題',
content: '這是一段內容'
}
}
//更新state
switch (action.type) {
case 'CHANGE_TITLE':
return {
...state,
title: action.newTitle
}
break;
default:
return state;
}
}
var store = createStore();
var { subscribe, dispatch, getState } = store;
subscribe(() => render(getState()))
dispatch(
{
type: 'CHANGE_TITLE',
newTitle: '我是通過dispatch函數容許修改後的新標題'
}
)
function render(state) {
document.getElementById('title').innerHTML = state.title;
document.getElementById('contents').innerHTML = state.content;
}
//調用部分
render(getState())
</script>
複製代碼
// 如今已是很是乾淨的純函數了
function createStore(appReducer) {
state = null;
var listeners = [];
function dispatch(action) {
state = appReducer(state, action)
listeners.map(e => e())
}
dispatch({})
function getState() {
return state
}
function subscribe(listener) {
listeners.push(listener);
}
return {
dispatch,
getState,
subscribe
}
}
// appReucer 函數
function appReducer(state, action) {
//初始化數據
if (!state) {
return {
title: '你好',
content: '歡迎光臨'
}
}
switch (action.type) {
case 'CHANGE_TITLE':
return {
...state,
title: action.newTitle
}
break;
default:
break;
}
}
//使用createStore部分
var store = createStore(appReducer);
var { dispatch,
getState,
subscribe } = store;
subscribe(() => render(getState()))
dispatch(
{
type: "CHANGE_TITLE",
newTitle: '我是通過dispatch函數容許修改後的新標題'
}
)
function render(state) {
document.getElementById('title').innerHTML = state.title;
document.getElementById('content').innerHTML = state.content;
}
render(getState());
複製代碼
這樣, 組件就無需維護本身的state 而使用外部引入的store裏面的stateredux
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import createStore from './createStore';
let appReducer = (state, action) => {
if (!state) {
return {
title: "這個是標題",
content: "這個是內容"
}
}
switch (action.type) {
case "CHANGE_TITLE":
return {
...state,
title: action.newTitle
}
case "CHANGE_CONTENT":
return {
...state,
content: action.newContent
}
default:
return state;
}
}
var store = createStore(appReducer)
//組件將不用去維護本身的state
class App extends Component {
constructor() {
super();
//訂閱觸發渲染的事件 this.setState
store.subscribe(() => {
this.setState(store.getState)
})
}
_chengeTitle(newTitle) {
//調用dispatch去修改store中的state, 隨後dispatch會 按順序執行listeners數組中訂閱的事件
store.dispatch({
type: "CHANGE_TITLE",
newTitle: newTitle
})
}
render() {
const { title, content } = store.getState();
{ console.info(store.getState()) }
return (
< div >
<h1>{title}</h1>
<p>{content}</p>
<button onClick={() => this._chengeTitle('您點擊了按鈕,標題已經被修改')}>點擊</button>
</div >
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
複製代碼