redux学习(二)

版权声明: https://blog.csdn.net/weixin_33768153/article/details/82842486

这次,在上次的基础上完成发布和订阅,具体代码看后边

redux.js 内容修改

思路,我们需要一个创建state的方法,返回一个对象,整个对象上有获取state数据的方法,派发事件的dispatch方法,以及提供监听事件的方法suscribe,因为我们只有一个state对象,还有一个action处理函数reducer函数

  • createStore方法

    返回一个对象,对象暴露一些我们需要的方法

/**
 * 创建state
 */
function createStore (reducer) {
    let state;
    let listeners = [] // 订阅数组

    // 监听函数
    function  subscribe(listener) {
        listeners.push(listener)
        // 返回一个函数,可以取消订阅
        return () => {
            listeners = listeners.filter(item => item !== listener)
        }
    }
    /**
     * 获取store
     */
    function getState () {
        // 做一个克隆,防止对象被修改
        return JSON.parse(JSON.stringify(state))
    }

    function dispatch (action) {
        state = reducer(state, action)
        // 状态更新以后,执行所有的监听函数
        listeners.forEach(fn => fn())
    }
    // 需要主动调用一次dispatch进行初始化
    dispatch({'type': '@@INIT'})
    return {
        getState,
        dispatch,
        subscribe
    }
}
  • reducer函数

该函数主要是更具不同的action,操作state对象

/**
 * 处理器
 * @param {object} state 状态对象
 * @param {object} action 需要修改的类型和值
 * @return {object} newState 返回新的state对象
 */
function reducer(state = initState, action) {
    switch (action.type) {
        case 'UPDATE_TITLE_COLOR':
            return {
                ...state, // 解构原来的状态
                title: { // 解构拿到title对象并重新赋值
                    ...state.title,
                    color: action.color // 覆盖color属性
                }
            }
            break;
        case 'UPDATE_CONTENT_TEXT':
            return {
                ...state, // 解构原来的状态
                content: { // 解构拿到title对象并重新赋值
                    ...state.content,
                    text: action.text // 覆盖color属性
                }
            }
            break;
        default:
            return state;
    }
}

修改后的完整代码

/**
 * 渲染数据
 * @param {object} appState  state对象
 */
function renderApp (appState) {
    renderTitle(appState.title)
    renderContent(appState.content)
}
/**
 * 渲染标题
 * @param {object} state 数据内容
 */
function renderTitle (state) {
    let el = document.querySelector('#title')
    el.innerHTML = state.text
    el.style.color = state.color
}
/**
 * 渲染内容
 * @param {object} state 数据内容
 */
function renderContent (state) {
    let el = document.querySelector('#content')
    el.innerHTML = state.text
    el.style.color = state.color
}

// 规定 如果想要修改appState只能荣国dispatch方法
// action是一个动作{type: 'UPDATE_TITLE_COLOR', color: 'orange'}
const UPDATE_TITLE_COLOR = 'UPDATE_TITLE_COLOR' // 更新标题颜色
const UPDATE_CONTENT_TEXT = 'UPDATE_CONTENT_TEXT' // 更新标题内容文本


/**
 * 创建state
 */
function createStore (reducer) {
    let state;
    let listeners = [] // 订阅数组

    // 监听函数
    function  subscribe(listener) {
        listeners.push(listener)
        // 返回一个函数,可以取消订阅
        return () => {
            listeners = listeners.filter(item => item !== listener)
        }
    }
    /**
     * 获取store
     */
    function getState () {
        // 做一个克隆,防止对象被修改
        return JSON.parse(JSON.stringify(state))
    }

    function dispatch (action) {
        state = reducer(state, action)
        // 状态更新以后,执行所有的监听函数
        listeners.forEach(fn => fn())
    }
    // 需要主动调用一次dispatch进行初始化
    dispatch({'type': '@@INIT'})
    return {
        getState,
        dispatch,
        subscribe
    }
}
// 创建新的state时使用的对象
let initState = {
    title: {
        color: 'red',
        text: '标题'
    },
    content: {
        color: 'green',
        text: '内容'
    }
}
/**
 * 处理器
 * @param {object} state 状态对象
 * @param {object} action 需要修改的类型和值
 * @return {object} newState 返回新的state对象
 */
function reducer(state = initState, action) {
    switch (action.type) {
        case 'UPDATE_TITLE_COLOR':
            return {
                ...state, // 解构原来的状态
                title: { // 解构拿到title对象并重新赋值
                    ...state.title,
                    color: action.color // 覆盖color属性
                }
            }
            break;
        case 'UPDATE_CONTENT_TEXT':
            return {
                ...state, // 解构原来的状态
                content: { // 解构拿到title对象并重新赋值
                    ...state.content,
                    text: action.text // 覆盖color属性
                }
            }
            break;
        default:
            return state;
    }
}

let store = createStore(reducer)

// 渲染视图
function render () {
    // 跟新试图
    renderApp(store.getState())
}
render()
// 订阅事件
store.subscribe(render)

// 3秒侯重新渲染
setTimeout(() => {
    store.dispatch({type: 'UPDATE_TITLE_COLOR', color: 'orange'})
    store.dispatch({type: 'UPDATE_CONTENT_TEXT', text: '新内容'})
}, 3000)

总结

上过上述简单的代码编写,我们实现了state对象的订阅发布,状态更新后自动刷新页面,接下来将继续深入学习redux 全部代码传送门

猜你喜欢

转载自blog.csdn.net/weixin_33768153/article/details/82842486
今日推荐