简体   繁体   中英

Changes don't render in React

I have array of items and searching items function, that returns another array. When I delete or edit item finded items changes don't render, but when search string has another value React render changes. I know that useEffect can resolve this problem, but dont what to put in callback.

How can resolve this problem?

export const ToDoList = (props: PropsType) => {
    const [searchQuery, setSearchQuery] = useState('')

    const searchedItems = useMemo(() => {
        return props.ToDoData.filter(item => item.text.includes(searchQuery))
    },
        [searchQuery])
    return (
            {props.ToDoData.length ?
                <>
                    <input
                        ...
                        onChange={e => setSearchQuery(e.target.value)}
                    />
                    <ItemsList
                        ...
                        items={
                            searchQuery ?
                                searchedItems :
                                props.ToDoData
                        }
                    />
                </> :
                ...
            }
    )
}

export const ItemsList = (props: PropsType) => {
    const [editedText, setEditedText] = useState('')

    const onDeleteItem = (id: number) => {
        props.dispatch(deleteItem(id))
    },
        onEditItemMode = (id: number, text: string) => {
            props.dispatch(setEditMode(true, id))
            setEditedText(text)
        },
        onEditText = (id: number) => {
            props.dispatch(setEditedTextInItem(id, editedText))
            props.dispatch(setEditMode(false, id))
            setEditedText('')
        },
        onToggleCompletedStatus = (id: number, status: string) => {
            ...
        }

    return (
            {props.items.length ?
                props.items.map((object) => (
                    <div
                        className="Item"
                        key={object.id}
                    >
                        {props.inEditMode.some((id: number) => id === object.id) ?
                            <>
                                <input
                                    value={editedText}
                                    onChange={e => { setEditedText(e.currentTarget.value) }}
                                />
                                <button onClick={() => onEditText(object.id)}>
                                    Change text
                                </button>
                            </> :
                            <>
                                <div className="Item__textBlock">
                                    <input
                                        type='checkbox'
                                        onClick={() => { onToggleCompletedStatus(object.id, object.status)}}
                                    />
                                    <span className={
                                        object.status === 'completed' ?
                                            'completed' :
                                            'in process'
                                    }>
                                        {object.text}
                                    </span>
                                </div>
                                <div className="Item__buttonBlock">
                                    <button
                                        className="Item__button"
                                        disabled={props.inEditMode.length !== 0}
                                        onClick={() => onEditItemMode(object.id, object.text)}
                                    >
                                        <img src={editImg} />
                                    </button>
                                    <button
                                        className="Item__button"
                                        onClick={() => { onDeleteItem(object.id) }}
                                    >
                                        <img src={removeImg} />
                                    </button>
                                </div>
                            </>
                        }
                    </div>
                )) :
                ...
            }
    )
}
// This code creates a list that is ONLY updated when searchQuery is updated
const searchedItems = useMemo(() => {
  return props.ToDoData.filter(item => item.text.includes(searchQuery))
}, [searchQuery]);

// This code creates the list every time the component renders,
// so it will always be correct
const searchedItems = props.ToDoData.filter(item => item.text.includes(searchQuery))

// If you absolutely need to optimize the render of this component
// This code will update the list whenever the reference for ToDoData is updated as well
const searchedItems = useMemo(() => {
  return props.ToDoData.filter(item => item.text.includes(searchQuery))
}, [searchQuery, props.ToDoData]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM