【问题标题】:Save the column header that is clicked on保存点击的列标题
【发布时间】:2022-07-17 04:23:39
【问题描述】:

我对 reactJS 真的很陌生。我有一个有两列的表。这是我的代码:

import React, { useState, useEffect } from 'react'
import { getUsers } from '../../services/userService'
import { useNavigate } from 'react-router-dom'
import Pagination from '@mui/material/Pagination'

const Table = () => {

    const navigate = useNavigate()
    
    const [users, setUsers] = useState([]);
    const [currentUsers, setCurrentUsers] = useState([]);
    const [search, setSearch] = useState('');
    const [isSorted, setIsSorted] = useState(false);
    const [valueHeader, setValueHeader] = useState({title: "",body: ""}); //Value header state
    const [sortedUsers, setSortedUsers] = useState([]);

    const pageItemCount = 15
    const [pageCount, setPageCount] = useState(0)
    const [currentPage, setCurrentPage] = useState(1)

    useEffect(async () => {
        try {
            const response = await getUsers(search);
            setUsers(response.data.users);
            setPageCount(Math.ceil(response.data.users.length / pageItemCount))
            setCurrentUsers(response.data.users.slice(0, pageItemCount))
        } catch (error) { }
    }, [search]);

    const sortFn = (userA, userB) => {
        // sort logic here, it can be whatever is needed
        // sorting alphabetically by `first_name` in this case
        return userA[valueHeader.body].localeCompare(userB[valueHeader.body]) //<== Use value of column header
      }
      
      useEffect(() => {
          if (isSorted) {
            setSortedUsers(currentUsers.slice().sort(sortFn))
          } else {
            setSortedUsers(currentUsers)
          }
        }, [isSorted, currentUsers, valueHeader]) //<== add valueHeader to dependency
      
      const toggleSort = ({target}) => {
        
        setIsSorted(!isSorted)
        setValueHeader({
          title: target.value,
          body: target.value === "name" ? "first_name" : "mobile"
        }) //<=== set state of value header
      }

    const changePage = (i) => {
        setCurrentPage(i)
        const startItem = ((i - 1) * pageItemCount) + 1
        setCurrentUsers(users.slice(startItem - 1, (pageItemCount * i)))
    }

    const handleChange = (event, value) => {
        changePage(value);
    }
        
            return (
                <div dir='rtl' className='bg-background mt-10 px-5 rd1200:px-30 overflow-auto'>
                   
                    <table className='w-full border-separate rounded-md'>
                        <thead>
                            <tr className='bg-text-secondary text-white shadow-sm text-center'>
                                <th className='p-2' onClick={(e) => toggleSort()}>name</th>
                                <th className='p-2' onClick={(e) => toggleSort()}>mobile</th>
                            </tr>
                        </thead>
                        <tbody>
                            {sortedUsers.map((item, index) =>
                                <tr key={item.id} className={index % 2 === 0 ? 'bg-white shadow-sm text-center' : 'bg-text bg-opacity-5 shadow-sm text-center'}>
                                    <td className='text-text text-sm p-2'>{item.first_name}</td>
                                    <td className='text-text text-sm p-2'>{item.mobile_number}</td> 
                                </tr>
                            )}
                        </tbody>
                    </table>
                    <Pagination className="mt-2 pb-20" dir='ltr' page={currentPage} count={pageCount} onChange={handleChange} variant="outlined" shape="rounded" />
                </div>
            )
        }
        
        export default Table

我想根据点击的列标题做出决定。例如,如果单击name 列标题,我想在useFunc 中使用first_name 的值,如果单击mobile 列标题,我想在useFunc 中使用mobile_number 值。

那么如何保存选择的列标题并在我的代码的其他部分使用它,例如在useFunc

【问题讨论】:

  • 您要保存整个列 DOM 还是只保存您选择的值?
  • 我有一个列标题name,该列的行由item.first_name 组成,同样我有一个列标题mobile,它的行由item.mobile_number 组成。我想保存单击了哪个列标题(namemobile),然后,例如,如果选择了name,我想在我的代码的其他部分使用item.first_name 的值(对于例如,如果您查看我的代码,我在sortFn 函数中使用了first_name 值)

标签: reactjs html-table


【解决方案1】:

如果你只想要值,更简单和安全的是直接将值传递给函数

import React, { useState, useEffect } from 'react'
    import { getUsers } from '../../services/userService'
    
    const Table = () => {
    
        const [users, setUsers] = useState([]);
        const [currentUsers, setCurrentUsers] = useState([]);
        const [isSorted, setIsSorted] = useState(false);
        const [sortedUsers, setSortedUsers] = useState([]);
    
    
        useEffect(async () => {
        try {
            const response = await getUsers(search);
            setUsers(response.data.users);
        } catch (error) { }
    }, [search]);
    
    const sortFn = (userA, userB) => {
      // sort logic here, it can be whatever is needed
      // sorting alphabetically by `first_name` in this case
      return userA.first_name.localeCompare(userB.first_name)
    }
    
useEffect(() => {
        if (isSorted) {
          setSortedUsers(currentUsers.slice().sort(sortFn))
        } else {
          setSortedUsers(currentUsers)
        }
      }, [isSorted, currentUsers])

    const toggleSort = () => {
      setIsSorted(!isSorted)
    }

    const useFunc = () => {
      //I want to decide based on the selected column header
    }
    
        return (
            <div dir='rtl' className='bg-background mt-10 px-5 rd1200:px-30 overflow-auto'>
               
                <table className='w-full border-separate rounded-md'>
                    <thead>
                        <tr className='bg-text-secondary text-white shadow-sm text-center'>
                            <th className='p-2' onClick={(e) => toggleSort("name")}>name</th>
                            <th className='p-2' onClick={(e) => toggleSort("mobile")}>mobile</th>
                        </tr>
                    </thead>
                    <tbody>
                        {sortedUsers.map((item, index) =>
                            <tr key={item.id} className={index % 2 === 0 ? 'bg-white shadow-sm text-center' : 'bg-text bg-opacity-5 shadow-sm text-center'}>
                                <td className='text-text text-sm p-2'>{item.first_name}</td>
                                <td className='text-text text-sm p-2'>{item.mobile_number}</td> 
                            </tr>
                        )}
                    </tbody>
                </table>
                
            </div>
        )
    }
    
    export default Table

【讨论】:

    【解决方案2】:

    解决方案

    将列标题的value 传递给state,然后将其用于您的代码的一部分,并将@​​987654323@ 添加到useEffect dependency 您设置SortedUsers 的位置,如下所示:

    import React, { useState, useEffect } from 'react'
    import { getUsers } from '../../services/userService'
    
    const Table = () => {
    
        const [users, setUsers] = useState([]);
        const [currentUsers, setCurrentUsers] = useState([]);
        const [isSorted, setIsSorted] = useState(false);
        const [valueHeader, setValueHeader] = useState({title: "",body: ""}); //Value header state
        const [sortedUsers, setSortedUsers] = useState([]);
    
    
        useEffect(async () => {
        try {
            const response = await getUsers(search);
            setUsers(response.data.users);
        } catch (error) { }
    }, [search]);
    
    const sortFn = (userA, userB) => {
      // sort logic here, it can be whatever is needed
      // sorting alphabetically by `first_name` in this case
      return userA[valueHeader.body].localeCompare(userB[valueHeader.body]) //<== Use value of column header
    }
    
    useEffect(() => {
        if (isSorted) {
          setSortedUsers(currentUsers.slice().sort(sortFn(userA, userB)))
        } else {
          setSortedUsers(currentUsers)
        }
      }, [isSorted, currentUsers, valueHeader, sortFn(userA, userB)]) //<== add valueHeader add sortFn(userA, userB) to dependency
    
    const toggleSort = ({target}) => {
      setIsSorted(!isSorted)
      if(target.value){
        setValueHeader({
        title: target.value,
        body: target.value == "name" ? "first_name" : "mobile_number"
      }) //<=== set state of value header
     }
    }
    
    const useFunc = () => {
      //I want to decide based on the selected column header
    }
    
        return (
            <div dir='rtl' className='bg-background mt-10 px-5 rd1200:px-30 overflow-auto'>
               
                <table className='w-full border-separate rounded-md'>
                    <thead>
                        <tr className='bg-text-secondary text-white shadow-sm text-center'>
                            <th className='p-2' onClick={toggleSort}>name</th>
                            <th className='p-2' onClick={toggleSort}>mobile</th>
                        </tr>
                    </thead>
                    <tbody>
                        {sortedUsers.map((item, index) =>
                            <tr key={item.id} className={index % 2 === 0 ? 'bg-white shadow-sm text-center' : 'bg-text bg-opacity-5 shadow-sm text-center'}>
                                <td className='text-text text-sm p-2'>{item.first_name}</td>
                                <td className='text-text text-sm p-2'>{item.mobile_number}</td> 
                            </tr>
                        )}
                    </tbody>
                </table>
                
            </div>
        )
    }
    
    export default Table
    

    【讨论】:

    • 当我点击页眉时,页面变为空白
    • 浏览器控制台日志中的错误是什么
    • 我解决了这个问题,谢谢。如果我们有超过 2 列,我们应该如何更改body: target.value == "name" ? "first_name" : "mobile_number"
    • 我发现了一个问题。无论我点击哪个列标题,body 都采用mobile_number 值。
    • @free 如果你有超过 2 列,只需创建一个函数,在这个函数中有 switch case 来返回你想要的值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    相关资源
    最近更新 更多