基于函數(shù)組件+redux+react-redux完成todolist的demo
demo地址:
https://github.com/jc5055/react-redux-hook
知識點(diǎn):
函數(shù)組件:
useState
:定義組件當(dāng)前的state的屬性
//isShowDelBtn:定義變量营密,初始值為false封救,作用域為當(dāng)前組件
//setIsShowDelBtn:更新變量isShowDelBtn昂灵,作用域為當(dāng)前組件
const [isShowDelBtn, setIsShowDelBtn] = useState(false)
//更新isShowDelBtn變量
setIsShowDelBtn(true)
useEffect
:副作用函數(shù)答憔,useEffect(()=>{ return }, par2)
通過par2參數(shù)的設(shè)置實(shí)現(xiàn)類組件函數(shù)中的狀態(tài)如‘ componentWillMount’,‘ componentDidUnmount’,‘ componentWillUpdate’
useEffect(()=>{
dispatch({
type:actionType.GET_ALL_TODO
})
}, [dispatch])
useCallback
: 用useCallback
定義的回調(diào)函數(shù)我衬,傳遞給子組件幽纷,配合子組件的memo
定義涂屁,減少不必要的組件刷新甸怕,與useEffect
類似
useRef
:組件內(nèi)獲取控件的輸入
//Top.js
//組件函數(shù)內(nèi)聲明
const inputRef = useRef()
//input 標(biāo)簽賦值
<input type="text"
placeholder="請輸入今天的任務(wù)清單甘穿,按回車鍵確認(rèn)"
onKeyDown={(event)=>{_handleKeyEvent(event)}}
ref={inputRef}
/>
//獲取值
const value = inputRef.current.value
redux:
使用redux
目的是解決組件樹深度過大,屬性需要依次傳遞梢杭,代碼閱讀性和維護(hù)性差的問題温兼。使用redux
基本要素:
大堂經(jīng)理根據(jù)用戶需求判斷具體的業(yè)務(wù)類型
銀行柜員更具業(yè)務(wù)類型,執(zhí)行具體的操作武契,從而實(shí)現(xiàn)用戶賬戶的更新
- 1.
store
(銀行數(shù)據(jù)庫):類似數(shù)據(jù)庫用來存儲數(shù)據(jù)募判,數(shù)據(jù)只能被reducer
訪問, - 2.
reducer
(銀行柜員):具體行為的操作咒唆,根據(jù)行為類型去執(zhí)行具體操作届垫,從而實(shí)現(xiàn)store
里面的數(shù)據(jù)更新 - 3.
actionType
(大堂經(jīng)理):具體代表類型
代碼實(shí)現(xiàn):
步驟一:定義行為類型actionType
//actionType.js
// 1. 存所有的Todo
const GET_ALL_TODO = 'get_all_todo'
export default {
GET_ALL_TODO,
}
步驟二:定義行為操作reducer
reducer
的基本形式為(state, action)=>{return state}
,
state
為對應(yīng)reducer
所控store
里面的數(shù)據(jù);
action
為具體行為全释,包括行為類型action.type
装处, 行為參數(shù)action.payload
為了代碼可讀性,使用combineReducers
對不通的reducer進(jìn)行合并成一個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的基礎(chǔ)的定義:actionType, reducer, store
react-redux:
知識點(diǎn)一:Provider標(biāo)簽
import react-redux
,在index.js
文件用Provider
標(biāo)簽對App
標(biāo)簽包裹李命,使得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')
);
知識點(diǎn)二:useSelector
在子組件中import react-redux
的API useSelector
可以獲取sotre對應(yīng)的數(shù)據(jù)登淘。
考慮到使用combineReducers
的將不通的reducer
進(jìn)行合并,因此要獲取特定reducer
設(shè)定的store
數(shù)據(jù)项戴,需要加上對應(yīng)的reducer
key如下文
//index.js 在此文件將不通的reudcer進(jìn)行統(tǒng)一
import {combineReducers} from 'redux'
import todoReducer from './todoReducer'
export const reducer = combineReducers({
todoReducer : todoReducer
})
//Top.js在此文件獲取todoReducer下聲明的store的數(shù)據(jù)
import {useSelector, useDispatch} from 'react-redux'
const todos = useSelector(state => state.todoReducer.todos)
知識點(diǎn)三:useDispatch
useDispatch的作用是在子組件中形帮,可以觸發(fā)對應(yīng)的reducer的行為操作槽惫,進(jìn)而實(shí)現(xiàn)對store的數(shù)據(jù)更新。具體操作步驟
- 1.
import {useDispatch}from 'react-redux'
- 2.在函數(shù)組件中定義對象
const dispatch = useDispatch()
- 3.
dispatch((type,payload))
的方式傳遞行為類型和行為所需要的參數(shù) - 4.
react-redux
會監(jiān)聽行為辩撑,改變store
存儲的數(shù)據(jù)
//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('輸入的內(nèi)容不為空')
return
}
const todo = {id:lastTodoId, title:value, finished:false}
dispatch({
type: actionType.ADD_ONE_TODO,
payload: todo
})
inputRef.current.value = ''
}
}