Skip to content

Instantly share code, notes, and snippets.

@huzidaha
Last active August 27, 2021 01:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save huzidaha/9a762224460ea5d8f771fb0f64252ed3 to your computer and use it in GitHub Desktop.
Save huzidaha/9a762224460ea5d8f771fb0f64252ed3 to your computer and use it in GitHub Desktop.
Using redux non-react project.
<!doctype html>
<html>
<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">
<script src='./jquery-v3.0.0.js'></script>
<script src='./redux-v3.6.0.min.js'></script>
<title>Document</title>
</head>
<body>
<div id="app">
<div id='header'></div>
<div id='body'></div>
<div id='footer'></div>
</div>
</body>
<script type="text/javascript">
/*======================== Redux Binding ======================= */
const shallowEqual = (objA, objB) => {
const hasOwn = Object.prototype.hasOwnProperty
if (Object.is(objA, objB)) return true
if (typeof objA !== 'object' || objA === null ||
typeof objB !== 'object' || objB === null) {
return false
}
const keysA = Object.keys(objA)
const keysB = Object.keys(objB)
if (keysA.length !== keysB.length) return false
for (let i = 0; i < keysA.length; i++) {
if (!hasOwn.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
return false
}
}
return true
}
const provider = (store) => (mapStateToProps) => (render) => {
/* 缓存 props 用来做计算 */
let props
const renderWrapper = () => {
const newProps = mapStateToProps(store.getState())
/* 如果新的结果和原来的一样,就不要重新渲染了 */
if (shallowEqual(props, newProps)) return
props = newProps
render(props)
}
/* 监听数据变化重新渲染 */
store.subscribe(renderWrapper)
return renderWrapper
}
/*====================== Reducer 和 store ===================== */
const appReducer = (state, action) => {
switch (action.type) {
case 'UPDATE_HEADER':
return Object.assign(state, { header: action.header })
case 'UPDATE_BODY':
return Object.assign(state, { body: action.body })
case 'UPDATE_FOOTER':
return Object.assign(state, { footer: action.footer })
default:
return state
}
}
const store = Redux.createStore(appReducer, {
header: 'Header',
body: 'Body',
footer: 'Footer'
})
const connect = provider(store)
/*====================== 构建渲染方法 ========================== */
/* header */
let renderHeader = (props) => {
console.log('render header')
$('#header').html(props.header)
}
renderHeader = connect((state) => ({
header: state.header
}))(renderHeader)
/* body */
let renderBody = (props) => {
console.log('render body')
$('#body').html(props.body)
}
renderBody = connect((state) => ({
body: state.body
}))(renderBody)
/* footer */
let renderFooter = (props) => {
console.log('render footer')
$('#footer').html(props.footer)
}
renderFooter = connect((state) => ({
footer: state.footer
}))(renderFooter)
/* 进行初始化渲染 */
const render = () => {
renderHeader()
renderBody()
renderFooter()
}
render()
/* 数据发生变化 */
setTimeout(() => {
store.dispatch({ type: 'UPDATE_HEADER', header: 'New Header' })
store.dispatch({ type: 'UPDATE_BODY', body: 'New Body' })
store.dispatch({ type: 'UPDATE_FOOTER', footer: 'New Footer' })
}, 1000)
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment