【问题标题】:how to delete all data and the update the page without refreshing using useEffect如何删除所有数据并更新页面而不使用 useEffect 刷新
【发布时间】:2021-09-23 20:18:48
【问题描述】:

我正在尝试使用带有事件处理程序的“全部删除”按钮删除 API 中的所有数据,它调用异步函数将我的 items 设置为空数组。这样做时,我希望它每次单击按钮时更新我的​​页面并更新页面数据,而无需使用useEffect 刷新页面。但是,仅当我刷新页面时页面才会更新(行为类似于componentDidMount())。经过一番研究,我意识到在数组参数的useEffect 钩子中添加items 会告诉DOM 重新渲染,只有当items 被更改时。但是,经过一番调试,我意识到每次刷新页面时都会调用handleDelete函数,这是我不希望它做的事情。我已经搜索并发现了很多关于这个问题的问题,但没有答案可以解决我的问题。有没有办法绕过它?我希望页面仅在我单击删除按钮时更新,仅此而已。

这是我的代码

export default function Dashboard() {
    const [items, setItems] = useState([]);

    const fetchList = async () => {
        await axios.get("/api/items").then((res) => {
            setItems(res.data.reverse());
        });
    };

    const handleDelete = () =>{
        axios.delete("/api/items").then((res)=>{
            setItems(res.data);
            console.log('-- res.data --', res.data)
        })
        
    }

    useEffect(() => {
        fetchList();
        console.log("fetchList activate")
    }, []);

    return (
        <div className={styles.dashboard_container}>
            <button className={styles.delete_all} onClick={handleDelete}>Delete All</button>
            {items.map((item) => {
                const { _id, name, phone, numberofpeople, time } = item;

                return (
                    <div className={styles.waitlist_item} key={_id}>
                        <h4>{name}</h4>
                        <h5>{phone}</h5>
                        <h4>{numberofpeople}</h4>
                        <h5>{moment(time).format("MMM Do, h:mm:ss A ddd")}</h5>
                    </div>
                );
...

这是我的后端路由器中处理删除请求的代码。

router.delete("/api/items", (req, res) => {
    Item.deleteMany({}, (err) => {
        if (err) {
            res.status(500);
        } else {
            res.json({ success: true });
        }
    });
});

【问题讨论】:

  • 您不需要在这里使用useEffectsetItems 应该可以完成这项工作。只需从后端返回一个空数组。 res.json([]) 应该可以工作。
  • 是的,这也可以,但是我想在单击按钮时更新我的​​页面。也许你的意思是useEffect(() =&gt; { fetchList(); console.log("fetchList activate") }, [items]);
  • 这里是什么意思:“更新我的页面”?您的页面,正是您“可视化”项目的那部分,将自动更新而无需刷新页面。我错过了什么?
  • “更新我的页面”是指当我点击按钮时,我想直观地删除页面上的所有数据。现在,按钮虽然删除了数据库中的数据,但是除非我刷新页面,否则它不会立即反映在页面上。
  • 好的,我们一起调试)你能不能在handleDelete函数中使用console.log('-- res.data --', res.data)。并且请删除第二个useEffect(在更改项目后第二次删除项目)它不应该在这里

标签: javascript node.js reactjs react-hooks


【解决方案1】:

关于后端的一些建议:

router.delete("/", (req, res) => {
    Item.deleteMany({}, (err) => {
        if (err) {
            response.status(500);
        } else {
            (res) => res.json({ success: true });
        }
    });
});

应该是res.status(500) 而不是response.status(500)

检查你的路线,这条似乎不正确,试试/itmes或者/api/items

(res) =&gt; res.json({ success: true });这部分好像也不对,应该是:

else {
   res.json({ success: true }); // or res.json([])
}

祝你好运!)

【讨论】:

  • 我已经更改了我的后端,现在我似乎从我的删除请求中得到了状态 200 响应。但是我收到了一个错误TypeError: items.map is not a function,我已在我的原始帖子中附加了那部分代码。我猜是因为现在数据库里面什么都没有,所以我们不能在空的items 上使用map()
  • 你试过 res.json([]) 吗?你在console.log('-- res.data --', res.data)中看到了什么
  • 我刚刚做到了!我在handleDelete() 函数中尝试了setItem([]),它现在可以工作了。现在res.data 输出对象{success: true}。非常感谢您的宝贵时间!
  • 所以基本上,删除数据库中的所有数据后,我猜items 变成了一个空对象,而map() 只适用于数组,这就是我收到错误的原因。如果我只是将setItem 设置为一个空数组,则该错误消失并且删除请求也成功。
【解决方案2】:

你的handleDelete在fetchList添加数据到item时被调用。

你可以这样做: 创建一个新状态

const [deleteAll, setDeleteAll] = useState(false);

将您的按钮更改为:

    <button className={styles.delete_all} onClick={() => setDeleteAll(true)}>Delete All</button>

并改变你的 useEffect

useEffect(() => {
        handleDelete();
        console.log("handleDelete activate")
    }, [deleteAll == true])

【讨论】:

  • handleDelete 仍然在刷新页面时被调用,并且由于某种原因被调用了两次。 fetchList 在控制台中被调用一次,handleDelete 被调用两次。
  • 当您的 fetchList 将数据设置为项目时,您的 handleDelete 将被调用。
  • 我现在看到了问题。所以每次我刷新页面时,项目都会更改两次,因此会调用两次 handleDelete。你有办法避免吗?
  • 我已经改变了答案。您可以创建一个只处理删除所有数据的状态。
猜你喜欢
  • 1970-01-01
  • 2018-10-24
  • 2018-04-25
  • 2014-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多