Redux学习笔记

2018-11-22  本文已影响9人  团猫咪爱吃玉米

Redux并不是只能在React应用中使用,而是可以在一般的应用中使用。
一、首先来看一下redux的工作流:

ca4884ebcb8e8253b0948de9707e865.png
ReactComponents可以看做'借书人',ActionCreators可以看做‘我要借本书’,Store可以看做图书管理员,Reducers可以看做'电脑/手册'
const action = {
  type: INPUT_CHANGE,
  value: e.target.value
}
// store.dispatch(action)
// actionCreators.js
export const onInputChange = (value) => ({
    type: INPUT_CHANGE,
    value
})
// store.dispatch(onInputChange(e.target.value))
const defaultStore = {
    inputValue: ''
}
export default (state = defaultStore, action) => {
    if (action.type === INPUT_CHANGE) {
       const newState = JSON.parse(JSON.stringify(state))
       newState.inputValue = action.value
       return newState
    }
  return state
}
 constructor (props) {
    super(props)
    this.state = store.getState()
    store.subscribe(this.handelStoreChange)
  }
 handelStoreChange () {
    this.setState(store.getState())
 }

二、store中的方法
Redux中的store是一个保存整个应用state对象树的对象,其中包含了几个方法,它的原型如下:

type Store = {
  dispatch: Dispatch
  getState: () => State
  subscribe: (listener: () => void) => () => void
  replaceReducer: (reducer: Reducer) => void
}

三、使用redux-thunk中间件实现ajax请求

import {createStore, applyMiddleware, compose} from 'redux'
import thunk from 'redux-thunk'
import reducer from './reducer'
const Combine =  compose(applyMiddleware(thunk), window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
var store = createStore(reducer, Combine)
export default store
export const initListData = (list) => ({
    type: INIT_LIST,
    list
})
export const getListData = () => {
    return dispatch => {
        axios.get('/api/todolist')
        .then((res) => {
            const data = res.data
            dispatch(initListData(data))
        })
    }
}
 componentDidMount () {
    // axios.get('/api/todolist')
    // .then((res) => {
    //   console.log(res.data);  
    //   store.dispatch(initListData(res.data))
    // })
    store.dispatch(getListData())  
  }

当我们把异步请求放在组件里的生命周期里时,随着代码量的增加,这个生命周期函数可能会变得越来越复杂,组件变得越来越大。所以建议还是将这种复杂的业务逻辑异步代码拆分到一个地方去管理。
现在借助redux-thunk 将异步请求放在actionCreator中去管理。
放在这里又带来一个好处,就是自动化测试变得很简单,比测试组件的生命周期函数简单的多。

最原始的dispatch方法,接收到一个对象之后会把这个对象传递给store.当有了中间件(对dispatch方法进行升级之后),当传递一个函数时,dispatch不会把这个函数直接传给store,而是先执行这个函数.所以dispatch会根据参数的不同做不同的事情。

四、使用redux-saga中间件实现ajax请求

import {createStore, applyMiddleware, compose} from 'redux'
import createSagaMiddleware from 'redux-saga'
import reducer from './reducer'
import todoSaga from './saga'
const sagaMiddleware = createSagaMiddleware()
const enhancers =  compose(applyMiddleware(sagaMiddleware),window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
var store = createStore(reducer, enhancers)
sagaMiddleware.run(todoSaga)
export default store
componentDidMount () {
  store.dispatch(getListData())  
}
export const initListData = (list) => ({
    type: INIT_LIST,
    list
})
export const getListData = () => ({
    type: GRT_INIT
})
import {put, takeEvery} from 'redux-saga/effects'
import {GRT_INIT} from './actiontypes'
import {initListData} from './actionCreators'
import axios from 'axios'
function* asyncGetList () {
    try {
        const res = yield axios.get('/api/todolist')
        const action = initListData(res.data)
        yield put(action)
    } catch (err) {
        console.error(err)     
    }
}
function* todoSaga () {
    yield takeEvery(GRT_INIT, asyncGetList)
}
export default todoSaga

五、react-redux的使用

<Provider /> 是由 React Redux 提供的高阶组件,用来让你将 Redux 绑定到 React

import React from 'react'
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import App from './App';

let store = createStore(todoApp)

ReactDOM .render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)
上一篇 下一篇

猜你喜欢

热点阅读