函数组件与react-redux的使用

2020-12-04  本文已影响0人  龙猫六六

基于函数组件+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基本要素:
大堂经理根据用户需求判断具体的业务类型
银行柜员更具业务类型,执行具体的操作,从而实现用户账户的更新

代码实现:

步骤一:定义行为类型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的数据更新。具体操作步骤

//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 = ''
        }
    }
上一篇下一篇

猜你喜欢

热点阅读