如何基于选项选择显示数组? (reactjs)

问题描述 投票:0回答:1

我想拥有一些选项,如果用户选择'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
            }
    }
})
arrays reactjs
1个回答
0
投票

将原始数组存储在另一状态。现在,您可以使用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>
    )
}
© www.soinside.com 2019 - 2024. All rights reserved.