我想拥有一些选项,如果用户选择'all',它将显示整个数组,如果'active',则仅显示未选中的数组项,并为所有选中的值显示'complete'。
但是,在选项之间切换时,我没有得到整个数组。例如,如果我选择“活动”,然后选择“完成”,然后选择“全部”,最后将什么也不会显示,因为切换阵列后为空。
我试图复制处于临时状态的现有数组,然后对其进行操作,但不起作用。
外观如下:
const [todo, dispatch] = useReducer((state: any, action: any): any => {
switch (action.type) {
//...
case 'SELECT':
switch (action.option) {
case 'all':
const temp1 = [...state]
return temp1
case 'complete':
const temp2 = [...state]
return temp2.filter((i: any) => i.isCheck === true)
case 'active':
const temp3 = [...state]
return temp3.filter((i: any) => i.isCheck === false)
default:
return state
}
}
}, [])
<select onChange={(e: any) => dispatch({ type: 'SELECT', option: e.target.value })}>
<option value="choose" selected>Choose</option>
<option value="all">All</option>
<option value="active">Active</option>
<option value="complete">Complete</option>
</select>
这里是整个组件:https://pastebin.com/Xr1gm4dV
任何解决方案或想法?
编辑:
const [options, setOptions] = useState([{}])
const [todo, dispatch] = useReducer((state: any, action: any): any => {
setOptions([...state])
switch (action.type) {
//...
case 'SELECT':
switch (action.option) {
case 'all':
setOptions([...state])
return options
case 'complete':
setOptions([...state])
return options.filter((i: any) => i.isCheck === true)
case 'active':
setOptions([...state])
return options.filter((i: any) => i.isCheck === false)
default:
return state
}
}
})
将原始数组存储在另一状态。现在,您可以使用todo数组进行渲染。 OriginalArray永远不会丢失。
const [originalArray, setOriginalArray] = useState([])
const [todo, dispatch] = useReducer((state: any, action: any): any => {
switch (action.type) {
//...
case 'SELECT':
switch (action.option) {
case 'all':
return originalArray
case 'complete':
return originalArray.filter((i: any) => i.isCheck === true)
case 'active':
return originalArray.filter((i: any) => i.isCheck === false)
default:
return state
}
}
})
编辑(在此处发布工作代码)
import React, { useRef, useReducer, useState } from 'react'
export default function App() {
const inputRef = useRef<HTMLInputElement | any>(null)
const handleSubmit = (e: any) => {
e.preventDefault()
if (inputRef.current?.value !== "") {
dispatch({
type: 'ADD_TODO',
payload: inputRef.current?.value,
id: editingIndex
})
}
inputRef.current && (inputRef.current.value = "")
}
const [editingIndex, setEditingIndex] = useState<null | number>(null)
const [selected, setSelected] = useState<'all' | 'active' | 'selected'>('all')
const [todo, dispatch] = useReducer((state: any, action: any): any => {
switch (action.type) {
case 'ADD_TODO':
setEditingIndex(null)
const tempState = [...state]
if (action.id) {
tempState[action.id] = { ...tempState[action.id], name: action.payload }
}
else {
tempState.push({
id: action.id | state.length,
name: action.payload,
isCheck: false,
toggleAll: false
})
}
return tempState
case 'CHECK_TODO':
return state.filter((item: any, index: any): any => {
if (index === action.id) {
item.isCheck = !item.isCheck
}
return item
})
case 'EDIT_TODO':
inputRef.current.focus()
inputRef.current.value = action.payload
return state
case 'DELETE_TODO':
return state.filter((item: any, index: any) => index !== action.id)
case 'CLEAR_TODOS':
return []
case 'ON_OFF':
const newState = state.map((item: any) => {
item.toggleAll = !item.toggleAll
return item
})
return newState.map((item: any) => {
item.isCheck = item.toggleAll
return item
})
default:
return state
}
}, [])
const handleEditing = (index: number, item: { name: string }) => {
setEditingIndex(index);
dispatch({
type: 'EDIT_TODO',
id: index,
payload: item.name
})
}
const todos = todo.map((item: any, index: number) => {
if(selected === 'active' && item.isCheck) return null
if(selected === 'complete' && !item.isCheck) return null
return (
<li key={index}>
<input
type="checkbox"
checked={item.isCheck}
onChange={() => dispatch({ type: 'CHECK_TODO', id: index })}
/>
{item.name}
<button onClick={() => handleEditing(index, item)}>/</button>
<button onClick={() => dispatch({ type: 'DELETE_TODO', id: index })}>x</button>
</li>
)
})
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder='Buy milk'
ref={inputRef}
/>
</form>
<button onClick={() => dispatch({ type: 'CLEAR_TODOS' })}>Clear</button>
<button onClick={() => dispatch({ type: 'ON_OFF' })}>On/Off</button>
<select value={selected} onChange={(e: any) => setSelected(e.target.value)}>
<option value="choose" selected>Choose</option>
<option value="all">All</option>
<option value="active">Active</option>
<option value="complete">Complete</option>
</select>
<ul>{todos}</ul>
</div>
)
}