javascript React中删除行后如何刷新表

mwkjh3gx  于 2023-01-29  发布在  Java
关注(0)|答案(1)|浏览(332)

这个问题看起来很常见,但我无法将其与我的场景联系起来。
我在React中有一个能够搜索的表,还有一个允许更新和删除数据的Actions列,它们在功能上与Spring Boot API和SQL数据库一起工作,但我的问题在于删除发生后刷新视图。
我在研究一个先例:https://codesandbox.io/s/62brk?file=/src/useTableSearch.js:0-1515
这是我的代码:
Columns.js:

export const userColumns = [

{
  title: "First Name",
  dataIndex: "firstName",
  key: "firstName"
},
{
  title: "LastName",
  dataIndex: "lastName",
  key: "lastName"
},
{
  title: "Pronoun(s)",
  dataIndex: "pronoun",
  key: "pronoun"
},
{
    title: "Date of Birth",
    // dataIndex: "birth",
    key: "birth",
    render: record => {
        return Object.values(record.birth.slice(0, 10))
    }
},
{
  title: "Address",
  key: "address",
  render: record => {
    return Object.values(record.address)
      .filter(val => typeof val !== "object")
      .join("");
  }
},
{
    title: "City",
    dataIndex: "city",
    key: "city"
},
{
    title: "Province",
    dataIndex: "province",
    key: "province"
},
{
    title: "Postal Code",
    dataIndex: "postalCode",
    key: "postalCode"
},
{
    title: "Phone",
    dataIndex: "phone",
    key: "phone"
},
{
    title: "Email",
    dataIndex: "email",
    key: "email"
},
{
    title: "Contact Preference",
    dataIndex: "contactPref",
    key: "contactPref"
},
{
    title: "Daytime Preference",
    dataIndex: "daytimePref",
    key: "daytimePref"
},
{
    title: "Actions",
    dataIndex: "actions",
        key: "actions",
} 
];

UseTableSearch.js:

// reference from: https://codesandbox.io/s/62brk?file=/src/useTableSearch.js:0-1515

import { useState, useEffect } from "react";

export const useTableSearch = ({ searchVal, retrieve }) => {
  const [filteredData, setFilteredData] = useState([]);
  const [origData, setOrigData] = useState([]);
  const [searchIndex, setSearchIndex] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setLoading(true);
    const crawl = (user, allValues) => {
      if (!allValues) allValues = [];
      for (var key in user) {
        if (typeof user[key] === "object") crawl(user[key], allValues);
        else allValues.push(user[key] + " ");
      }
      return allValues;
    };
    const fetchData = async () => {
      const { data: users } = await retrieve();
      setOrigData(users);
      setFilteredData(users);
      const searchInd = users.map(user => {
        const allValues = crawl(user);  
        return { allValues: allValues.toString() };
      });
      setSearchIndex(searchInd);
      if (users) setLoading(false);
    };
    fetchData();
  }, [retrieve]);

  useEffect(() => {
    if (searchVal) {
      const reqData = searchIndex.map((user, index) => {
        if (user.allValues.toLowerCase().indexOf(searchVal.toLowerCase()) >= 0)
          return origData[index];
        return null;
      });
      setFilteredData(
        reqData.filter(user => {
          if (user) return true;
          return false;
        })
      );
    } else setFilteredData(origData);
  }, [searchVal, origData, searchIndex]);

  return { filteredData, loading };
};

showUsers.js:

// reference from: https://codesandbox.io/s/62brk?file=/src/useTableSearch.js:0-1515

import React, { useState } from "react";
import { Link} from "react-router-dom";
import { Table, Input } from "antd";
import axios from "axios";
import  { userColumns} from './Columns'
import { useTableSearch } from "./UseTableSearch";
import '../styling/ShowUsers.css';
import userService from '../services/UserServices';
const { Search } = Input;

// const deleteUser = (id) => {

//用户服务.删除用户(id)

//axios.delete(`http://localhost:8080/clients/${index}`)
    // .then(res => {
       //  const users = this.state.users.filter(item=> item.id !== id);
       //  this.setState({ users });
    });
}

// const [users, setUsers] = useState([]); //{ data }
// const [user, setUser] = useState('');

const showUsers = async () => {
    const { data } = await axios.get(
        "http://localhost:8080/clients/"
    ) return {data}
}

    // .then((res) => {
    //     setUsers({users: res.data});
    // })

    // const rows = users.map((item, index) => {
    //     return ( 
                // <tr>
          
   //              <td>
    //             <Link to={"/editUser/" + user.id} className="btn btn-outline-success my-2 // text-center mr-2">Update User</Link>
    //             <button className="btn btn-outline-primary text-center mr-2" onClick={() // => {deleteUser(user.id); }} /> 
         //             </td>
                     
                //     </tr>
       //          
                )  
   //  })      
 //    }

export default function App() {

    // const [rows, setRows] = useState(dbValues);

    // const deleteRow = (number) => {
    //     let copy = [...rows]

    //     copy = copy.filter((item, index) => number != index)

    //     setRows(copy);
    // }

    // const [users, setUsers] = useState([]);

    const [searchVal, setSearchVal] = useState(null);

    const { filteredData, loading } = useTableSearch({
        searchVal,
        retrieve: showUsers
    });

    return (
        <>
            <Search id="searchBox"
                onChange={e => setSearchVal(e.target.value)}
                placeholder="Search"
                enterButton
                style={{ position: "sticky", top: "0", left: "0" }}
            />
        
            <br /> <br />
            <Table
                rowKey="name"
                dataSource={filteredData}
                columns={userColumns}
                loading={loading}
                pagination={false}
                
            />
        </>
    );
}

我尝试过的方法包括在Columns.js的Actions列中放入一个呈现组件。然后我将deleteUser函数放在Columns数组的顶部,它可以处理Axios请求。除了需要手动刷新页面以反映数据库中更改的数据之外,这种方法几乎完全奏效。

return  (
     <td>

        <Link to={"/editUser/" + user.id} className="btn btn-outline-success my-2 text-center mr-2">Update User</Link>
        <button className="btn btn-outline-primary text-center mr-2" onClick={() => {deleteUser(user.id); //RefreshComponent && <RefreshComponent />}}>Delete User</button> 

    </td>
)

并删除组件:

const deleteUser =  (id) => {

     userService.deleteUser(index)

    axios.delete(`http://localhost:8080/clients/${index}`)
}

这种方法的局限性是我无法与剩余内容进行比较,而这是删除后响应的常用方法:

deleteUser(index) {
    console.log(index);

    userService.deleteUser(index)

        axios.delete(`http://localhost:8080/clients/${index}`)
    .then(res => {

        const users = this.state.users.filter(item=> item.id !== index);
        this.setState({ users });
    })
}

我研究的其他东西包括this example,它做了我所寻找的事情,但是我不能将它的方法转换成我的代码(另外,我的代码使用的是Ant Design)。
showUsers.js中注解掉的行反映了在Columns文件之外的单独返回组件中单独添加按钮的尝试,但这也毫无结果。
最后,不允许在Columns文件中使用useState挂接(通常在这种情况下有效),无论是在该文件外部,还是在Delete按钮的事件触发器内的函数内(在列的return组件内)。
我已经实现了一个单独的Delete组件或Refresh组件,可以将其导入到Columns(例如RefreshComponent && <RefreshComponent />)中,并在删除发生时调用。同样,我尝试使用useNavigate作为调用另一个get请求和刷新视图的方法,但这也是不可能的。
最后,我研究了SO上的一些解决方案,如this one,它们使用基于类的方法,而我通常使用钩子,而且我也找不到一个决定性的先例,用于围绕搜索函数和单独的列导入构建的示例。
总的来说,我的思想在这个问题上循环往复,我不能确切地弄清楚如何在删除请求通过后实现视图刷新。
先谢谢你!

o75abkj4

o75abkj41#

让我分享一个想法,React背后的想法之一是能够根据注册的状态的变化,使UI(从较大的UI到单个组件)自动呈现或重新呈现(无论你喜欢什么)。
因此,作为一名开发人员,您必须实现的是尝试将该用户数据集作为状态注册到负责呈现该表的组件。
如果你使用的是函数方法,你可以用钩子useState()来实现,如果你使用的是类方法,你可以用钩子this.setState()来实现,或者从更高的组件(通常是父组件)更新传递给这个组件的props
因此,您面临的挑战是能够更新此状态,例如,当用户被删除时。因此,如果您设法在注册的数据集更改后更新它,那么React组件(在本例中为表)将重新呈现。

相关问题