函數組件與react-redux的使用

基于函數組件+redux+react-redux完成todolist的demo

demo地址:

https://github.com/jc5055/react-redux-hook

知識點:

函數組件:

useState:定義組件當前的state的屬性

//isShowDelBtn:定義變量,初始值為false,作用域為當前組件
//setIsShowDelBtn:更新變量isShowDelBtn,作用域為當前組件
 const [isShowDelBtn, setIsShowDelBtn] = useState(false)

//更新isShowDelBtn變量
setIsShowDelBtn(true)

useEffect:副作用函數,useEffect(()=>{ return }, par2)通過par2參數的設置實現類組件函數中的狀態如‘ componentWillMount’,‘ componentDidUnmount’,‘ componentWillUpdate’

 useEffect(()=>{
        dispatch({
            type:actionType.GET_ALL_TODO
        })
    }, [dispatch])

useCallback: 用useCallback定義的回調函數,傳遞給子組件,配合子組件的memo定義,減少不必要的組件刷新,與useEffect類似

useRef:組件內獲取控件的輸入

//Top.js
//組件函數內聲明
 const inputRef = useRef()

//input 標簽賦值
 <input type="text"
                   placeholder="請輸入今天的任務清單,按回車鍵確認"
                   onKeyDown={(event)=>{_handleKeyEvent(event)}}
                   ref={inputRef}
            />

//獲取值
const value = inputRef.current.value

redux:

使用redux目的是解決組件樹深度過大,屬性需要依次傳遞,代碼閱讀性和維護性差的問題。使用redux基本要素:
大堂經理根據用戶需求判斷具體的業務類型
銀行柜員更具業務類型,執行具體的操作,從而實現用戶賬戶的更新

  • 1.store(銀行數據庫):類似數據庫用來存儲數據,數據只能被reducer訪問,
  • 2.reducer(銀行柜員):具體行為的操作,根據行為類型去執行具體操作,從而實現store里面的數據更新
  • 3.actionType(大堂經理):具體代表類型

代碼實現:

步驟一:定義行為類型actionType

//actionType.js
// 1. 存所有的Todo
const GET_ALL_TODO = 'get_all_todo'

export default {
    GET_ALL_TODO,
}

步驟二:定義行為操作reducer

reducer的基本形式為(state, action)=>{return state},
state為對應reducer所控store里面的數據;
action為具體行為,包括行為類型action.type, 行為參數action.payload

image.png

為了代碼可讀性,使用combineReducers對不通的reducer進行合并成一個reducer,賦值給store

import {combineReducers} from 'redux'
import todoReducer from './todoReducer'

export const reducer = combineReducers({
    todoReducer : todoReducer
})

步驟三:定義store

將reducer賦值給store,完成store的新建

import {createStore} from 'redux'
import {reducer} from "./reducer/index"
const store = createStore(reducer)

export default store

至此完成了redux的基礎的定義:actionType, reducer, store

react-redux:

知識點一:Provider標簽

import react-redux,在index.js文件用Provider標簽對App標簽包裹,使得App下的組件都能獲取store的值

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {Provider} from 'react-redux'
import store from "./store/store";
ReactDOM.render(
  <Provider store={store}>
    <App />
   </Provider>,
  document.getElementById('root')
);

知識點二:useSelector

在子組件中import react-redux的API useSelector可以獲取sotre對應的數據。
考慮到使用combineReducers的將不通的reducer進行合并,因此要獲取特定reducer設定的store數據,需要加上對應的reducer key如下文

//index.js 在此文件將不通的reudcer進行統一
import {combineReducers} from 'redux'
import todoReducer from './todoReducer'

export const reducer = combineReducers({
    todoReducer : todoReducer
})


//Top.js在此文件獲取todoReducer下聲明的store的數據
import {useSelector, useDispatch} from 'react-redux'
const todos = useSelector(state => state.todoReducer.todos)

知識點三:useDispatch

useDispatch的作用是在子組件中,可以觸發對應的reducer的行為操作,進而實現對store的數據更新。具體操作步驟

  • 1.import {useDispatch}from 'react-redux'
  • 2.在函數組件中定義對象const dispatch = useDispatch()
  • 3.dispatch((type,payload))的方式傳遞行為類型和行為所需要的參數
  • 4.react-redux會監聽行為,改變store存儲的數據
//App.js
import {useSelector, useDispatch} from 'react-redux'
useEffect(()=>{
        dispatch({
            type:actionType.GET_ALL_TODO
        })
    }, [dispatch])

// Top.js
    const dispatch = useDispatch()

    const _handleKeyEvent = (e)=>{
        const lastTodoId = todos.length === 0 ? 0: todos[todos.length - 1].id
        if (13 === e.keyCode){
            const value = inputRef.current.value
            if (!value.trim()){
                alert('輸入的內容不為空')
                return
            }
            const todo = {id:lastTodoId, title:value, finished:false}
            dispatch({
                type: actionType.ADD_ONE_TODO,
                payload: todo
            })
            inputRef.current.value = ''
        }
    }
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容