首页 » 记事本 » 聊一聊我对redux的理解

聊一聊我对redux的理解

react是单向数据流动的的框架,数据可以从顶层组件依次传递给层级最深的组件。

react组件通信

react组件树形结构犹如家族关系:

爷爷要和小红通信:爷爷告诉爸爸,爸爸告诉小红。爸爸要和叔叔通信:可以将两者交互的state提升至爷爷,通过爷爷state的改变来完成通信使命。

现实项目中需求远比上面的关系要复杂的多,状态便变得难于管理。如果能把需要通信的组件状态放到一个store的地方,这样只需要去store更新状态与之相关的视图自动更新,这样是不是简单了很多了呢? 于是就有了redux这样的框架,redux是JavaScript 状态容器,提供可预测化的状态管理。

redux

redux 设计思想:

从例子入手

来看一个最简单的例子:

//reducers/index.js
export default (state = 0, action) => {
    switch (action.type) {
        case 'INCREMENT':
            return state + 1
        case 'DECREMENT':
            return state - 1
        default:
            return state
    }
}

state = 0 此时等效于:var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;通常用来定一个初始状态。

import counter from './reducers'
const store = createStore(counter)

class Counter extends Component {
    static propTypes = {
        value: PropTypes.number.isRequired,
        onIncrement: PropTypes.func.isRequired,
        onDecrement: PropTypes.func.isRequired
    }

    incrementIfOdd = () => {
        if (this.props.value % 2 !== 0) {
            this.props.onIncrement()
        }
    }

    incrementAsync = () => {
        setTimeout(this.props.onIncrement, 1000)
    }

    render() {
        const {value, onIncrement, onDecrement} = this.props
        return (
            <p>
                Clicked: {value} times
                {' '}
                <button onClick={onIncrement}>+</button>
                {' '}
                <button onClick={onDecrement}>-</button>
                {' '}
                <button onClick={this.incrementIfOdd}>Increment if odd</button>
                {' '}
                <button onClick={this.incrementAsync}>Increment async</button>
            </p>
        )
    }
}
const render = () => ReactDOM.render(
    <Counter
        value={store.getState()}
        onIncrement={() => store.dispatch({type: 'INCREMENT'})}
        onDecrement={() => store.dispatch({type: 'DECREMENT'})}
    />,
    rootEl
)

render()
store.subscribe(render)

redux API:

store.getState用来获取store内部的状态。

store.dispatch用来将用户的行为交给reducer,reducer根据用户行为的类型改变state。

store.subscribe用来将改变添加到监听列表,在store.dispatch调用时以此触发监听列表。

combineReducers

const rootReducer = combineReducers({
  postsByReddit,
  selectedReddit
})

combineReducers方法会将参数中的reducer存储在起内部并返回一个新的reducer函数, 用来被createStore方法使用。

applyMiddleware

import thunk from 'redux-thunk'
const middleware = [thunk];
if (process.env.NODE_ENV !== 'production') {
    middleware.push(createLogger());
}

const store = createStore(
    reducer,
    applyMiddleware(...middleware)
)

Middleware 可以让你包装 store 的 dispatch 方法来达到你想要的目的。同时, middleware 还拥有“可组合”这一关键特性。多个 middleware 可以被组合到一起使用,形成 middleware 链。

redux-thunk

dispatch方法默认只能接收一个对象,当使用redux-thunk中间件时会改写dispatch方法使,当其参数为function时,则会将function执行结果(通常返回一个对象)传递给原来的dispatch。function内通常会异步请求,根据请求状态可以实现控制反转

在上面的例子我们需要手动添加store变动所需要触发的更新,能不能修改状态自动触发所需要的更新呢?如果有这样的疑问请继续往下看:

redux与react

redux提供了react-redux模块,react-redux提供了2个核心的方法 Provider 与 connet:Provider作为项目的根组件用来共享Store提供的方法,这样子组件connect即可接收到类似dispatch/getState这样的方法。

其原理参见我之前的文章《redux-react Provider 与 connet》,本文不再详述。

此文章发表在 记事本. 将 固定链接 加入收藏.