一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。 大家好,我是大帅子,今天我们接着昨天的来介绍 todos案例, 我们直接开始,这边给大家附上仓库地址 , gitee.com/dashuaizi/t…
修改状态
1.我们直接开始干,我们先尝试修改状态,先定义一个按钮,然后在把状态渲染出来
{todos.map(item => <li key={item.id} style={{ listStyle: 'none' }}>
{item.name} {item.isDone ? '已完成' : '未完成'}
<button onClick={() => update(item.id)}>给我变</button>
</li>)}
- 因为我们这时要用到
dispatch了,但是我们发现用原来的办法会报错,我这边有解决方案
const dispatch = useDispatch<Dispatch<{ type: string, payload: any }>>()
// 改变状态
const update = (id: number) => {
// console.log(id);
dispatch(updateState(id))
}
- 然后我们在
/store/action/todos中写处理函数,先定义类型,下面直接使用
type TodoAction =
{
type: 'UPDATE_STATE' // 字面量类型
payload: number
}
export const updateState = (id: number): TodoAction => {
return {
type: 'UPDATE_STATE',
payload: id
}
}
4.最后一步我们只需要在/store/reducer/todos.ts中写入改变状态的代码,一样我们需要先定义好状态
export type TodoType = {
id: number
name: string
isDone: boolean
}
//在那边传值过来这边直接,做判断
export default function todos(state = initValue, action: any): TodoType[] {
// 修改状态
const id = action.payload
if (action.type === 'UPDATE_STATE') {
return state.map(item => {
if (item.id === id) {
return { ...item, isDone: !item.isDone }
} else {
return { ...item }
}
})
}
return state
}
useRef的泛型参数
useRef 接收一个泛型参数,源码如下
/**
* `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument
* (`initialValue`). The returned object will persist for the full lifetime of the component.
*
* Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable
* value around similar to how you’d use instance fields in classes.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#useref
*/
function useRef<T>(initialValue: T): MutableRefObject<T>;
interface MutableRefObject<T> {
current: T;
}
useRef的泛型参数用于指定current属性的值的类型
解决方法
使用useRef操作DOM,需要明确指定所操作的DOM的具体的类型,否则current属性会是null
正确语法:
const inputRef = useRef<HTMLInputElement>(null)
添加
- 设置一个添加按钮,跟一个输入框 ,然后获取表单的值
<input type="text" onKeyUp={keyUP} ref={refInput} />
<button onClick={add} >添加</button>
// 添加
const add = (e: any) => {
console.log(e);
// 这边作为非空断言 , 不然会报错
if (refInput.current) {
// console.log(refInput.current.value);
dispatch(addTodos(refInput.current.value))
}
}
- 我们在进去
action/todos.ts中进行操作
type TodoAction =
{
type: 'add_TODO'
payload: TodoType
}
export const addTodos = (name: string): TodoAction => {
// console.log(data, 333);
return {
type: 'add_TODO',
payload: {
id: Date.now(),
name,
isDone: false
}
}
}
- 我们因为不用新加模块,如果新加模块的话,我们就要在
/store/reducers/index.ts中添加模块
import { combineReducers } from 'redux'
import todos from './todos'
import channel from './channel'
const rootReducer = combineReducers({
todos, // 新加模块
})
export default rootReducer
- 最后我们要在
/store/reducer/todos.ts中间进行最后的代码
export type TodoType = {
id: number
name: string
isDone: boolean
}
const initValue: TodoType[] = [
{
id: 1,
name: '吃饭',
isDone: false,
}
]
export default function todos(state = initValue, action: any): TodoType[] {
// 添加
else if (action.type === 'add_TODO') {
console.log(action.payload, 2323423);
return [...state, action.payload]
}
return state
}
- 我们可以拓展一下,写一个按下键盘松开事件,可以检测我们按下的是哪个键,enter键的发送信息
<input type="text" onKeyUp={keyUP} ref={refInput} />
// 回车事件 这个东西大家可以直接复制,以后直接用就行了,改一下事件名的事
const keyUP = (e: any) => {
if (e.keyCode === 13 && refInput.current) {
dispatch(addTodos(refInput.current.value))
}
}
最后我们来讲删除,
与其说讲,我更想让你们自己尝试一下,大家可以先试试怎么做,但是步骤我还是放在下面
1.我们先设置删除的按钮,再写一个处理事件
<ul>
{todos.map(item => <li key={item.id} style={{ listStyle: 'none' }}>
<button onClick={() => del(item.id)}>删除</button>
</li>)}
</ul>
// 删除
const del = (id: number) => {
dispatch(delState(id))
}
2. 我们在 /store/action/todos 定义类型跟处理事件
type TodoAction =
{
type: 'DEL_TODO'
payload: number
}
export const delState = (id: number): TodoAction => {
return {
type: 'DEL_TODO',
payload: id
}
}
3. 我们需要在 /storereducers/todos.ts 中间做最后的处理
export default function todos(state: TodoType[] = initValue, action: any): TodoType[] {
// 删除
else if (action.type === 'DEL_TODO') {
return state.filter(item => item.id !== id)
}
return state
}
好了,到此我们的小案例就结束了,不知道大家有没有学会没有,以上是我自己的理解,讲的不好, 欢迎留言我这边一定会第一时间给大家解答,喜欢的可以点赞收藏,
🐣---->🦅 还需努力!大家一起进步啊!!!!