天天看點

使用react-redux的過程及常見的坑 -- 01使用react-redux的過程及常見的坑 – 01如果有其他這部分的坑可以私信我,我會持續補充

使用react-redux的過程及常見的坑 – 01

使用 react-redux和redux

1.安裝

npm install redux react-redux -S
           

2.配置使用

大多數教程裡面示範了非常複雜的配置流程,他們将store、action、reducer分離開來,使新手看不明白

是以我将不會拆分這些部分進而更簡單明了的示範它們的使用方法

(1)建立store.js

// 引入redux
import {createStore} from 'redux'

// 配置預設state資料
const defaultState = {
    inputValue: '123',
    list: []
}

// 當改變store中的資料時,會自動執行reducer,reducer函數會對資料進行處理,并傳回一個新的state
/**
 * 
 * @param state 舊的state
 * @param action 包含兩個參數分别為type和value
 * @returns {{inputValue: string, list: []}} 新的state
 */
const reducer = (state = defaultState, action) => {
    return state
}

// 建立store
const store = createStore(reducer)

// 将store抛出供元件使用
export default store
           

(2)配置index.js

// 引入子元件
import TodoList from './TodoList'
// 引入react-redux中的Provider
import {Provider} from 'react-redux'
// 引入store
import store from "./store";

// 将store綁定到Provider的store屬性上
// 被Provider包裹的元件都可以自由通路到store
const App = (
    <Provider store={store}>
        <TodoList></TodoList>
    </Provider>
)
// 挂載
ReactDOM.render(
  App,
  document.getElementById('root')
);
           

(3)配置子元件todoList.js

// 正常引入React
import React, {Component} from "react";
// 引入react-redux的連接配接方法
import {connect} from 'react-redux'
// 正常元件聲明方式
class todoList extends Component{
    render() {
        return (
            <div>
                <div>
                
                    // 通路store中的資料  使用this.props.inputValue
                    // 調用dispatch,使用this.props.inputChange
                    <input type="text" value={this.props.inputValue} onChange={this.props.inputChange}/>
                    
                    <button>送出</button>
                </div>
                <ul>
                    <li>JSJSJS</li>
                </ul>
            </div>
        )
    }
}

// 将store的資料取出并通過props傳到此元件
const stateToProps = (state) => {
    return {
        inputValue: state.inputValue
    }
}

// 将dispatch的方法取出并通過props傳到此元件
const dispatchToProps = (dispatch) => {
    return {
        inputChange(e){
            console.log(e.target.value)
        }
    }
}

// 通過connect函數将store與此元件進行連接配接
// 連接配接後會傳回另一個函數,需要把元件的類傳入此函數然後抛出
export default connect(stateToProps,dispatchToProps)(todoList)
           

(4)配置一個簡單的reducer

我們将store.js中的reducer更改一下,使reducer有能力更改store中的資料    
```
const reducer = (state = defaultState, action) => {
        if(action === 'changeInput') {
            // 對store中的資料state進行深度拷貝,這是一個簡便方式
            let newState = JSON.parse(JSON.stringify(state))
            newState.inputValue = action.value
            return newState
        }
        return state
    }
```
           

(5)出發reducer

在todoList.js中修改dispatchToProps函數
```
const dispatchToProps = (dispatch) => {
    return {
        inputChange(e){
            let action = {
                type: 'changeInput',
                value: e.target.value
            }
            dispatch(action)
        }
    }
}
```
           

(6)後記

在正式開發中,通常要求将reducer、action、store分離開來,使代碼更加簡潔明了  
以上操作方式都會使用的情況下,對資料的增删改查操作都沒什麼太大問題  
如果在開發中需要大量使用異步處理,如ajax、延時等,需要使用redux-thunk或redux-saga等中間件操作
           
截至目前遇到的常見的坑
  1. 頁面好用,但會出現報錯

    Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.

    問了一下百度,大多數都說需要安裝一個名為redux-thunk的中間件,我試了一下沒解決,後來發現問題

    export default connect(stateToProps,dispatchToProps)(todoList)

    這裡傳入的時候 stateToProps和dispatchToProps後面都不要加括号,傳入了一個函數執行後傳回的參數,結果當然會報錯

如果有其他這部分的坑可以私信我,我會持續補充