redux使用數據流程以下:
javascript
由上可知,咱們須要一個函數來保存狀態值,並暴露出修改,獲取,同步的方法,下面開始進行推理html
沒有react-create-app,安裝後再建立reduxLearnjava
npm install -g create-react-app
複製代碼
react-create-app reduxLearn複製代碼
刪除public
和src
下全部的文件,建立reduxLearn/public/index.html
react
新建reduxLearn/src/index.js
git
設置一個變量來保存咱們想要的效果github
let state = {
title: {
color: 'red',
text: '標題'
},
content: {
color: 'pink',
text: '內容'
}
}
複製代碼
建立渲染方法npm
function renderApp(appState) {
renderTitle(appState.title)
renderContent(appState.content)
}
function renderTitle(title) {
let titleEle = document.getElementById('title')
titleEle.innerHTML = title.text
titleEle.style.color = title.color
}
function renderContent(content) {
let contentEle = document.getElementById('content')
contentEle.innerHTML = content.text
contentEle.style.color = content.color
}
function render() {
renderApp(state)
}複製代碼
若是在執行 renderApp(initState)以前的某個地方執行了initState=nullredux
頁面就會報錯 TypeError: Cannot read property 'title' of null
數組
function createStore() {
let state = {
title: {
color: 'red',
text: '標題'
},
content: {
color: 'pink',
text: '內容'
}
}
}複製代碼
變量被保護起來了,須要用的時候怎麼獲取呢?bash
function createStore() {
let state = {
title: {
color: 'red',
text: '標題'
},
content: {
color: 'pink',
text: '內容'
}
}
//獲取狀態
function getState() {
return state
}
return {
getState
}
}
//使用狀態
let store = createStore(reducer)
...
function render() {
renderApp(store.getState())
}
複製代碼
若是咱們想改變這個狀態的值怎麼辦呢?
const TITLE_COLOR = 'TITLE_COLOR'
const TITLE_TEXT = 'TITLE_TEXT'
const CONTENT_COLOR = 'CONTENT_COLOR'
const CONTENT_TEXT = 'CONTENT_TEXT'複製代碼
//派發
function dispatch(action) {
switch (action.type) {
case TITLE_COLOR:
state.title.color = action.color
break;
case TITLE_TEXT:
state.title.text = action.text
break;
case CONTENT_COLOR:
state.content.color = action.color
break;
case CONTENT_TEXT:
state.content.text = action.text
break;
default:
return state
}
}
複製代碼
store.dispatch({ type: TITLE_COLOR, color: 'blue' })
store.dispatch({ type: TITLE_TEXT, text: '修改標題了' })
render()
複製代碼
function createStore(reducer) {
let state;
//派發
function dispatch(action) {
state = reducer(state, action)//經過reducer處理返回結果值
}
//獲取狀態
function getState() {
return state
}
//執行一次,目的是設置默認值
dispatch({ type: "@@TYPE_INIT_STATE" })
return {
dispatch,
getState,
}
}
複製代碼
//聲明初始值
const initState = {
title: {
color: 'red',
text: '標題'
},
content: {
color: 'pink',
text: '內容'
}
}
//reducer 這裏返回的數據應是新對象->state = reducer(state, action)//經過reducer處理返回結果值
function reducer(state = initState, action) {
switch (action.type) {
case TITLE_COLOR:
return { ...state, title: { ...state.title, color: action.color } }
case TITLE_TEXT:
state.title.text = action.text
return { ...state, title: { ...state.title, text: action.text } }
case CONTENT_COLOR:
state.content.color = action.color
return { ...state, content: { ...state.content, color: action.color } }
case CONTENT_TEXT:
return { ...state, content: { ...state.content, text: action.text } }
default:
return state
}
}複製代碼
let store = createStore(reducer)複製代碼
發現每次修改都要從新調用render()
才生效,很麻煩,若是咱們在每次修改時添加監聽事件,觸發訂閱模式,則能夠一勞永逸
function createStore(reducer) {
let state;
//訂閱添加監聽函數數組
let listeners = []
//派發
function dispatch(action) {
state = reducer(state, action)
//訂閱
listeners.forEach(l => l())
}
//訂閱,返回一個取消訂閱的方法
function subscribe(listener) {
listeners.push(listener)
return function () {
listeners = listeners.filter(item => item != listener)
}
}
//獲取狀態
function getState() {
return state
}
dispatch({ type: "@@TYPE_INIT_STATE" })
return {
dispatch,
getState,
subscribe
}
}
複製代碼
store.subscribe(render)複製代碼
store.subscribe(render)
setTimeout(() => {
store.dispatch({ type: TITLE_COLOR, color: 'blue' })
store.subscribe(render)()//取消訂閱
store.dispatch({ type: TITLE_TEXT, text: '修改標題了' })
}, 1000);
複製代碼
export default function createStore(reducer) {
let state;
let listeners = []
//派發
function dispatch(action) {
state = reducer(state, action)
//訂閱
listeners.forEach(l => l())
}
//訂閱,返回一個取消訂閱的方法
function subscribe(listener) {
listeners.push(listener)
return function () {
listeners = listeners.filter(item => item != listener)
}
}
//獲取狀態
function getState() {
return state
}
dispatch({ type: "@@TYPE_INIT_STATE" })
return {
dispatch,
getState,
subscribe
}
}
複製代碼
import createStore from './createStore'
export {
createStore,
}複製代碼
import { createStore } from './redux'複製代碼
要想保護數據要找個函數包裹起來createStore
,可變的因素reducer
能夠經過參數傳遞進來,對數據的操做能夠在函數內部暴露給外面getstate,dispatch,subscribe
在使用時直接把使用函數賦值給變量store
,使用變量.函數store.getState()
便可
https://github.com/XinYueXiao/interviewHighlights/tree/master/reduxLearn