Redux流程 + 如何调用 redux 的 state

这篇会介绍的几种调用 redux state 的方式,都是工作上遇到的,算是长了知识,网路上也许会有相关教学,但这边会以初学者的角度跟大家分享

首先:什麽是 Redux

Redux 一个用於应用程序状态管理的开源 JavaScript 库。Redux 经常与 React 搭配运用,但其也可以独立使用。 - 取自维基百科

是我的话,我会说是一个可以让你把特殊资料全域的方法

因为有了 redux 我们不用再在各个 Component 中传递 Props,当然除了 redux 还是有别的方法做资料的存储,不过不是这篇的重点,所以这边先跳过

感觉很好用欸,那要怎麽用?

在进入 redux 之前,你必须要知道 redux 三巨头,就跟 NBA 一样一定会有三巨头,分别是:action, store, reducer,什麽鬼?行动商店减速器?感觉很有商机欸,先别急嘛...这边我先讲一下各自所做的事,再搭配图片你一定会更加了解!

题外话:很多人在学 redux 都喜欢使用图书馆的例子,不过像我们这种不喜欢读书才来当工程师的人来说一点说服力都没有啊...

警告:这边会有点黄色成份,所以觉得不适的话可以先跳到图片部分

在故事开始前我先订一些角色,方便我构思我的故事:

  • 客人
  • 柜台阿姨
  • 小姐(小美)

故事开始:

首先你(客人)今天被老板到处刁难,想说下班去找小美,顺便聊聊今天遇到的不快,不过今天刚好星期五所以人很多,柜台阿姨只好拿出纸笔,让大家写下希望找的小姐姓名,轮到你时,你把手上写着小美名字的卡片给了柜台阿姨(action),这时阿姨会去後台看看今天小美有没有来上班(store),最後小美给了你封信,说今天身体不舒服,想早点休息(reducer)

来!故事结束了。你是不是想看什麽特殊剧情?没有!我们是来学习 redux 的

各位老司机,是不是了解 redux 的流程了?简单来说,会使用 action 做触发事件的动作,并且透过 store 传递给 reducer 你所传递过去的资料(卡片),并且待 reducer 处理完资料後回传给你新的 state

image

上图是我觉得做得很好的流程图,试着把上面的字改成故事里面的角色,相信就会比较了解

讲完 redux 了,那 redux 的 state 呢?

关於 redux 的 state 有很多种调用方式,先说一下为什麽需要调用 redux 的 state?

就好像,今天小美其实写好卡片了。但因为没有人帮忙传递,所以你一直在外面乾等,眼巴巴看着你朋友幸福洋溢的走出来,相信你不会想经历的...

等一下的程序码会专注於有改变得部分,如果没贴代表跟最上面一样

且路径是视自己专案而定,不然会没效果

基础 redux 环境

// termianl

npm install --save redux
npm install react-redux --save

// action.js

export const BUTTON_CLICK = 'BUTTON_CLICK'

export const buttonClick = (payload) => {
  return {
    type: BUTTON_CLICK,
    payload: value,
  }
}

// store.js

import { createStore } from 'redux'
import reducer from './reducer'

const store = createStore(reducer)
export default store

// reducer.js

const defaultState = {
    name: 'jan' // 初始资料
}

const reducer (state = defaultState,action)=>{
    switch (action.type) {
        case BUTTON_CLICK:
            const name = state.name;
            const value = action.payload;
            return {...state, name: value}
            break;
        default: // 一定要写
            return state
            break;
    }
}

export default reducer;

// App.js - 调用页面 (一律使用 useDispatch()打 action)

import React from 'react'
import { useDispatch } from 'react-redux'
import { BUTTON_CLICK } from '../src/redux/action'

function App() {
  const dispatch = useDispatch()
  const buttonClick = () => {
    dispatch({ type: BUTTON_CLICK, payload: 'bill' })
  }
  return (
    <div>
      <button onClick={() => buttonClick()}>取的reducer</button>
    </div>
  )
}

export default App

// index.js

import React from 'react'
import ReactDOM from 'react-dom'

import { Provider } from 'react-redux'
import store from './src/store'

import App from './App'

ReactDOM.render(
  <Provider store={store}>
    {/* 将store作为props传递给其他component */}
    <App />
  </Provider>,
  document.getElementById('app')
)

使用 react-redux 的 mapStatetoProps (class component)

  • 使用 mapStateToProps 不过 Hooks 的 useSelector 出现後,就被代替了

  • 可以省略 constructor 里面的 this.state = store.getState()

  • 把 name 当作 props 来做传递

// App.js

import React from 'react'
import { connect } from 'react-redux'

class Map extends React.Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div>
        <h1>{this.props.name}</h1>
      </div>
    )
  }
}

const mapStateToProps = (state) => ({
  name: state.name,
})

const MapState = connect(mapStateToProps)(Map)

export default MapState

使用 react-redux 的 useSelector (Hooks)

  • 这边直接用 useSelector 抓取 state 里面的 name,写法更为直观
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { BUTTON_CLICK } from '../src/redux/actionType'

function App() {
  const dispatch = useDispatch()
  const name = useSelector((state) => state.name)
  const buttonClick = () => {
    dispatch({ type: BUTTON_CLICK, payload: 'bill' })
  }
  return (
    <div>
      <button onClick={() => buttonClick()}>取的reducer</button>
      <h1>{name}</h1>
    </div>
  )
}

export default App

以上就是基本的 redux state 调用方法,现在基本上都用第二种了,除非你的专案还没导入 Hooks


<<:  Day 02 HTML<表格标签>

>>:  Day 12 让你的广告活动可以超乎预料的好

冒险村14 - counter cache

14 - counter cache 在许多情况下,会需要统计一对多关联的资料数量。举例来说像是 U...

06 APCS 考试内容 Overview

APCS 分为两个大部分,观念题和实作题。观念题以选择题为主,旨在测试考生对於程序语言的观念是否正确...

建立第一个单元测试(golang)-1(Day20)

当我们建立起最简单的RESTful api後,接下来我们就要将测试也放到我们的程序中了 在golan...

Mysql有那些变数?如何设定?以及有那些值得认识的配置选项呢?

前文提到mac电脑启动mysql的方式为 brew services start mysql 其实我...

CMoney菁英软件工程师战斗营_Week 7

Hi again 本周大部分时间都是在准备游戏专题 在专题中也会需要上周所提及的图片切个制作动画 由...