reactjs 在React Firebase待办事项列表应用程序中过滤后对任务进行排序

bvn4nwqk  于 2023-01-08  发布在  React
关注(0)|答案(1)|浏览(99)

我不知道在我正在开发的React Firebase待办事项列表应用中过滤任务后,如何按“创建”值对任务进行排序。我尝试在数据库查询中添加以下行,但它不起作用:

const q = query(collection(db, 'tasks'), where("uid", "==", user?.uid), orderBy("created"));

下面是完整的代码,不包括导入:

export default function Todo() {

    const [name, setName] = useState("");
    const [tasks, setTasks] = useState([]);
    const [user, loading, error] = useAuthState(auth);
    const [searchInput, setSearchInput] = useState("");
    const [filteredTasks, setFilteredTasks] = useState([]);

    //function for automatically retrieving items
    useEffect(() => {
        const q = query(collection(db, 'tasks'), where("uid", "==", user?.uid));
        onSnapshot(q, (querySnapshot) => {
            setTasks(querySnapshot.docs.map(doc => ({
                id: doc.id,
                data: doc.data()
            })))
        })
    }, [])

    //function for loading filtered tasks
    useEffect(() => {
        setFilteredTasks(tasks
            .filter(task => task.data.name.match(searchInput))
        );
    }, [searchInput, tasks])

    //function for getting the value of the main input
    function handleChange(e) {
        e.preventDefault();
        setName(e.target.value);
        console.log(name);
    }

    //function for getting the value of the search input
    function handleSearchChange(e) {
        e.preventDefault();
        setSearchInput(e.target.value)
    }

    //function for adding items to firestore
    const handleAdd = async (e) => {
        e.preventDefault();
        if (name === "") {
            alert("Please enter some text");
            clearInput();
            return;
        }
        try {
            await addDoc(collection(db, 'tasks'), {
                name: name,
                completed: false,
                created: Timestamp.now(),
                uid: user?.uid,
            })
            clearInput();
        } catch (err) {
            alert(err)
        }
    }

    //function for adding strikethrough to an item
    function handleClick(e) {
        if (e.detail === 2) {
            console.log("double click");
            e.currentTarget.classList.toggle('double-clicked');
        }
    }

    //function for updating an item
    const handleUpdate = async (taskName, id) => {
        let name = prompt("Please enter a new name", taskName);
        if (name === null) {
            return;
        }
        const taskDocRef = doc(db, 'tasks', id)
        try {
            await updateDoc(taskDocRef, {
                name: name,
            })
            clearInput();
        } catch (err) {
            alert(err)
        }
    }

    //function for deleting an item
    const handleDelete = async (id) => {
        console.log(id);
        const taskDocRef = doc(db, 'tasks', id)
        try {
            await deleteDoc(taskDocRef)
            clearInput();
        } catch (err) {
            alert(err)
        }
    }

    //function for clearing and focusing the input
    function clearInput() {
        let input = document.querySelector("input");
        input.value = '';
        input.focus();
        setName("");
    }

    return (
        <div>
            <div>
                <div>
                    <h1>To Do List App</h1>
                    <p>Double click to mark an item off.</p>
                </div>
                <input
                    id="input"
                    type="text"
                    value={name}
                    onChange={handleChange}
                    autoFocus
                />
                <button
                    className="add-button"
                    type="submit"
                    onClick={handleAdd}
                >
                    <IoMdAddCircle />
                </button>
            </div>

            <ol>
                {filteredTasks.map(task => (
                    <li
                        className="task-list-items"
                        id={task.id}
                        key={task.id}
                        completed={task.data.completed}
                        onClick={handleClick}
                    >
                        {task.data.name}
                        <button
                            className="edit-button"
                            onClick={() => handleUpdate(task.data.name, task.id)}
                        >
                            <BsFillPencilFill />
                        </button>
                        <button
                            className="delete-button"
                            onClick={() => handleDelete(task.id)}
                        >
                            <BsFillTrashFill />
                        </button>
                    </li>
                ))}
            </ol>

            <div>
                <h5>Search for an item by name</h5>
                <input
                    id="search-bar"
                    type="text"
                    value={searchInput}
                    onChange={handleSearchChange}
                />
            </div>

        </div>
    );
};

当我添加新任务时,即使没有筛选,它们也会以错误的顺序出现。
数据库如下所示:

5anewei6

5anewei61#

我弄清楚了如何在过滤后对任务进行排序。以下是我更新的代码:

export default function Todo() {

    const [name, setName] = useState("");
    const [tasks, setTasks] = useState([]);
    const [user, loading, error] = useAuthState(auth);
    const [searchInput, setSearchInput] = useState("");
    const [filteredTasks, setFilteredTasks] = useState([]);

    //function for automatically retrieving items
    useEffect(() => {
        const q = query(collection(db, 'tasks'), where("uid", "==", user?.uid));
        onSnapshot(q, (querySnapshot) => {
            setTasks(querySnapshot.docs.map(doc => ({
                id: doc.id,
                data: doc.data()
            })))
        })
    }, [])

    //function for loading filtered tasks
    useEffect(() => {
        setFilteredTasks(tasks
            .filter(task => task.data.name.match(searchInput))
        );
    }, [searchInput, tasks])

    //function for getting the value of the main input
    function handleChange(e) {
        e.preventDefault();
        setName(e.target.value);
        console.log(name);
    }

    //function for getting the value of the search input
    function handleSearchChange(e) {
        e.preventDefault();
        setSearchInput(e.target.value)
    }

    //function for adding items to firestore
    const handleAdd = async (e) => {
        e.preventDefault();
        if (name === "") {
            alert("Please enter some text");
            clearInput();
            return;
        }
        try {
            await addDoc(collection(db, 'tasks'), {
                name: name,
                completed: false,
                created: Timestamp.now(),
                uid: user?.uid,
            })
            clearInput();
        } catch (err) {
            alert(err)
        }
    }

    //function for adding strikethrough to an item
    function handleClick(e) {
        if (e.detail === 2) {
            console.log("double click");
            e.currentTarget.classList.toggle('double-clicked');
        }
    }

    //function for updating an item
    const handleUpdate = async (taskName, id) => {
        let name = prompt("Please enter a new name", taskName);
        if (name === null) {
            return;
        }
        const taskDocRef = doc(db, 'tasks', id)
        try {
            await updateDoc(taskDocRef, {
                name: name,
            })
            clearInput();
        } catch (err) {
            alert(err)
        }
    }

    //function for deleting an item
    const handleDelete = async (id) => {
        console.log(id);
        const taskDocRef = doc(db, 'tasks', id)
        try {
            await deleteDoc(taskDocRef)
            clearInput();
        } catch (err) {
            alert(err)
        }
    }

    //function for clearing and focusing the input
    function clearInput() {
        let input = document.querySelector("input");
        input.value = '';
        input.focus();
        setName("");
    }

    //function for sorting tasks after they are filtered
    function sortTasks(array) {
        array.sort((a, b) => (a.data.created < b.data.created ? -1 : 1));
        return array;
    }

    return (
        <div>
            <div>
                <div>
                    <h1>To Do List App</h1>
                    <p>Double click to mark an item off.</p>
                </div>
                <input
                    id="input"
                    type="text"
                    value={name}
                    onChange={handleChange}
                    autoFocus
                />
                <button
                    className="add-button"
                    type="submit"
                    onClick={handleAdd}
                >
                    <IoMdAddCircle />
                </button>
            </div>

            <ol>
                {sortTasks(filteredTasks).map(task => (
                    <li
                        className="task-list-items"
                        id={task.id}
                        key={task.id}
                        completed={task.data.completed}
                        onClick={handleClick}
                    >
                        {task.data.name}
                        <button
                            className="edit-button"
                            onClick={() => handleUpdate(task.data.name, task.id)}
                        >
                            <BsFillPencilFill />
                        </button>
                        <button
                            className="delete-button"
                            onClick={() => handleDelete(task.id)}
                        >
                            <BsFillTrashFill />
                        </button>
                    </li>
                ))}
            </ol>

            <div>
                <h5>Search for an item by name</h5>
                <input
                    id="search-bar"
                    type="text"
                    value={searchInput}
                    onChange={handleSearchChange}
                />
            </div>

        </div>
    );
};

相关问题