Redux 入门

学习 Redux 是个十分痛苦的过程,因为你有可能不知道 Redux 和 React-Redux 是两个不同的东西,而且一堆看起来很新的概念总能把新手绕晕。

这篇文章将从一个简单的例子开始讲 Redux 到底要怎么使用。建议先学习 EventHub 或者看我的另一篇文章 React 的兄弟组件通信,因为 Redux 的主要思想就是 EventHub 思想。

纯 JS + Redux

先说下需求,首先要有一个数字,点击按钮数字加1,没了。不过这个过程要使用到 Redux,也就是说这个数字要放在全局变量中。

这里就用一个简单的 index.html 写就完了。HTML 代码如下:

接下来写 JS。

function add() {
    store.dispatch({ type: 'add', payload: 1 }) // 1. dispatch 一个 action
}

function render() {
    let app = document.querySelector('#app')
    app.innerHTML = `
    Clicked: ${store.getState()} times
    
` } function stateChanger(state, action) { if (state === undefined) { return 0 } else { if (action.type === 'add') { let newState = state + action.payload return newState // 2. 根据操作生成新的 state 触发一个事件 } } } let store = Redux.createStore(stateChanger) render(store) store.subscribe(render) // 3. 接收到事件,重新 render

这里说明一下运行的步骤:

  1. 首先运行 render() 将标签都 append 到 document 上,并在按钮上绑定 add 回调
  2. 点击了按钮执行 add() ,然后 dispatch 一个 action(相当于触发了名为“add”的一个事件)
  3. 因为在 Redux.createStore(stateChanger) 时,Redux 会监听 action(也就是事件)的触发,所以会执行 stateChanger 里的代码
  4. 因为在 store.subscribe(render) 在 if-else 里修改了新的 state 后,Redux 会重新执行 render() 函数,从而更新整个页面

Redux 的用法就是这么简单!但是为什么我们看官方档看得想死呢?因为加了 React,后来的所有看起来很变态的使用方法都是为了解决:怎么让代码更好分离,怎么获取全局变量等。思想还是那个思想。

React + Redux

现在我们正式加入 React,使用官方提供的create-react-app来创建应用。App 组件写成这样:

// App.js
class App extends Component {
    add1() {
        this.props.store.dispatch({  // 1. dispatch 一个 action
            type: 'add',
            payload: 1
        })
    }
    render() {
        return (
            
Clicked: {this.props.value} times
) } } export default App

在入口文件去初始化 Redux:

const stateChanger = (state, action) => {
    if (state === undefined) {
        return 0
    }
    else {
        if (action.type === 'add') {
            let newState = state + action.payload
            return newState // 2. 根据操作生成新的 state 触发一个事件
        }
        else {
            return state
        }
    }
}

function render() {
    ReactDOM.render(
        ,
        document.getElementById('root')
    )
}

const store = createStore(stateChanger)

store.subscribe(render) // 3. 接收到事件,重新 render

render()

感觉好像没什么变化呀,不就将一个 index.html 分成了 index.js 和 App.js 么?但是这里涉及到怎么去获取 store 的问题。

如果一两个组件就用 props 来传 store 就好了,但是如果组件很深,那么 store 就要像传家保一样一层层往下传,十分麻烦。

为了解决这个问题, React 社区又推出了一个新的工具:React-Redux。注意这个和 Redux 没有太大关系。为了说明这两个是不一样,我放下他们的官网:Redux 官网,React-Redux 官网。

React + Redux + React-Redux

先说明这个工具就只是用来让别的组件可以访问到 store 而已,所以它只有 4 个API,其中主要我们要用的就 2 个:Provider, connect。简单理解:

  1. Provider:将 store 放在顶层组件
  2. connect:将 store 里的数据和 dispatch action (也就是触发事件)和当前组件绑定,使得该组件可以自由访问和修改 store

现在修改上面两个文件:

// index.js
const stateChanger = (state, action) => {
    if (state === undefined) {
        return { n: 0 }
    }
    else {
        if (action.type === 'add') {
            let newState =  {
                n: state.n + action.payload
            }
            return newState
        }
        else {
            return state
        }
    }
}

const store = createStore(stateChanger)

ReactDOM.render(
    
        
    ,
    document.getElementById('root')
)

下面的 App.js

class App extends Component {
    render() {
        return (
            
Clicked: {this.props.n} times
) } } // 将部分 store 里的 state 映射到 props 上 function mapStateToProps(state) { return { n: state.n } } // 将 dispatch action 相关操作映射到 props 上 function mapDispatchToProps(dispatch) { return { add: () => { dispatch({ type: 'add', payload: 1 }) } } } export default connect(mapStateToProps, mapDispatchToProps)(App)

来对比一下两份代码:

少了哪些?

  1. 不用 store.subscribe(render),Provider 会在更新值后自动重新渲染
  2. 不用在组件 App 里写回调函数了,在 mapDispatchToProps 里声明事件,这个事件会就负责调用 dispatch(action)

多了哪些?

  1. 要在 App 组件外再去套一层
  2. 将 App 组件和 state,调用 dispatch 的函数连接起来。连接(映射)后的结果是,所有 state 数据和调用 dispatch 的函数都可以从 this.props 得到

这样就解决了组件访问,修改 store 里的 state 问题。唉,绕了一大圈就为了搞这些事。

那些变态概念

Redux 为什么这么难,是因为它将很简单的概念给了个新名字罢了。

Redux

  1. Store:存放全局数据的一个东西,但是要通过 store.getState() 来获取全局数据
  2. State:全局数据
  3. Action:对应 EventHub 里的事件,actionType 就是事件名,payload 就是传入的数据
  4. Dispatch:触发事件,如 dispatch({ type: 'add', payload: 1}),就是指触发一个名为“add”的事件,并带上了数据 1
  5. Reducers:对应触发事件后的回调函数,如我们平时听到的onError = xxx,这个 xxx 就是 Reducer,这个例子的 Reducer 就是 stateChanger

React-Redux

  1. Provider:可以看成一个包住最外面 App 的一个标签,这个标签传入 store 后,通过某些方法所有组件都可以访问到 store
  2. mapStateToProps:将存在 store 里的数据放在这个组件的 props 上
  3. mapDispatchToProps:将需要调用 dispatch 的函数放在这个组件的 props 上
  4. connect:将上面两个东西和这组件联系起来

是不是很烦,嗯,我也是这么觉得的,明明很简单的概念,就是不好好说话。
(完)

你可能感兴趣的:(Redux 入门)