过滤器功能(过滤器)的第一次更改不会触发 onChange [重复]

Posted

技术标签:

【中文标题】过滤器功能(过滤器)的第一次更改不会触发 onChange [重复]【英文标题】:onChange dosent get triggered on first change for filter function (filterFn) [duplicate] 【发布时间】:2022-01-23 18:12:35 【问题描述】:

过滤器函数filterFn第一次更改时触发onChangedosent,changeDepartmentIdFilter函数dosent在第一次更改示例时更改departmentIdFilter的值

如果我写

苹果

它仅用于控制台

应用

这里是代码:

const Department = () => 


    let [department, setDepartment] = useState([])
    let [filteredDepartment, setFilteredDepartment] = useState([])
    
    let [values, setValues] = useState(
        modalTitle: '',
        departmentName: '',
        departmentId: 0,

        departmentIdFilter: "",
        departmentNameFilter: "",
        departmentsWithoutFilter: [],
    )

    useEffect (() => 
        getDepartments()
    , [])


    let filterFn = () =>
        let departmentIdFilter = values.departmentIdFilter
        let departmentNameFilter = values.departmentNameFilter


        let filteredData = filteredDepartment.filter(
            function(el)
                return el.DepartmentId.toString().toLowerCase().includes(
                    departmentIdFilter.toString().trim().toLowerCase()
                ) &&
                el.DepartmentName.toString().toLowerCase().includes(
                    departmentNameFilter.toString().trim().toLowerCase()
                )

            
        )
        setDepartment(filteredData)

    


    let changeDepartmentIdFilter = (e) => 
        setValues(...values, 'departmentIdFilter': e.target.value)
        filterFn()
    
    
    
    let changeDepartmentNameFilter = (e) => 
        console.log(e.target.value)
        setValues(...values, 'departmentNameFilter': e.target.value)
        filterFn()
    


    let getDepartments = async () => 
        let response = await fetch (variables.API_URL + "department")
        let data = await response.json()

        setDepartment(data)
        setFilteredDepartment(data)
    

  
    return (
        <div>

            <button type="button" className="btn btn-primary m-2 float-end" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick=() => addClick()>Add Department</button>

            <table className="table table-striped">
                <thead>
                    <tr>
                        <th>
                            <input className="form-control m-2" onChange=(e) => changeDepartmentIdFilter(e) placeholder='Filter' />
                            DepartmentId
                        </th>
                        <th>
                            <input className="form-control m-2" onChange=(e) => changeDepartmentNameFilter(e) placeholder='Filter' />
                            DepartmentName
                        </th>
                        <th>
                            Options
                        </th>
                    </tr>
                </thead>
                <tbody>
                    department.map((dep) => 

                        <tr key=dep.DepartmentId>
                            <td>dep.DepartmentId</td>
                            <td>dep.DepartmentName</td>
                            <td>
                                

                                <button type="button" className="btn btn-light mr-1" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick=() => editClick(dep)>
                                    
                                </button>


                                <button type="button" className="btn btn-light mr-1" onClick=() => deleteClick(dep.DepartmentId)>
                                    
                                </button>

                            </td>
                        </tr>
                        )
                </tbody>
            </table>

            <div className="modal fade" id="exampleModal" tabIndex="-1" aria-hidden="true">
                <div className="modal-dialog modal-lg modal-dialog-centered">
                    <div className="modal-content">
                        <div className="modal-header">
                            <h5 className="modal-title">values.modalTitle</h5>

                            <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close">
                            </button>

                        </div>

                        <div className="modal-body">
                            <div className="input-group mb-3">
                                <span className="input-group-text">Department Name</span>
                                <input name = 'departmentName' type="text" className="form-control" value=values.departmentName onChange=(e) => changeDepartmentName(e) />
                                /* <input type="text" className="form-control" value=departmentName onChange=changeDepartmentName /> */
                            </div>

                            values.departmentId == 0 ?
                                <button type="button" className="btn btn-primary float-start" onClick=() => createClick()>Create</button> :
                                null
                            

                            values.departmentId != 0 ?
                                <button type="button" className="btn btn-primary float-start" onClick=() => updateClick()>Edit</button> :
                                null
                            

                        </div>

                    </div>
                </div>
            </div>

        </div>
    )


export default Department

只有相关代码的简化代码:

const Department = () => 


let [department, setDepartment] = useState([])
let [filteredDepartment, setFilteredDepartment] = useState([])

let [values, setValues] = useState(
    modalTitle: '',
    departmentName: '',
    departmentId: 0,

    departmentIdFilter: "",
    departmentNameFilter: "",
    departmentsWithoutFilter: [],
)

useEffect (() => 
    getDepartments()
, [])


let filterFn = () =>
    let departmentIdFilter = values.departmentIdFilter
    let departmentNameFilter = values.departmentNameFilter


    let filteredData = filteredDepartment.filter(
        function(el)
            return el.DepartmentId.toString().toLowerCase().includes(
                departmentIdFilter.toString().trim().toLowerCase()
            ) &&
            el.DepartmentName.toString().toLowerCase().includes(
                departmentNameFilter.toString().trim().toLowerCase()
            )

        
    )
    setDepartment(filteredData)




let changeDepartmentIdFilter = (e) => 
    setValues(...values, 'departmentIdFilter': e.target.value)
    filterFn()



let changeDepartmentNameFilter = (e) => 
    console.log(e.target.value)
    setValues(...values, 'departmentNameFilter': e.target.value)
    filterFn()



 return (
        <div>

            <button type="button" className="btn btn-primary m-2 float-end" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick=() => addClick()>Add Department</button>

            <table className="table table-striped">
                <thead>
                    <tr>
                        <th>
                            <input className="form-control m-2" onChange=(e) => changeDepartmentIdFilter(e) placeholder='Filter' />
                            DepartmentId
                        </th>
                        <th>
                            <input className="form-control m-2" onChange=(e) => changeDepartmentNameFilter(e) placeholder='Filter' />
                            DepartmentName
                        </th>
                        <th>
                            Options
                        </th>
                    </tr>
                </thead>
                <tbody>
                    department.map((dep) => 

                        <tr key=dep.DepartmentId>
                            <td>dep.DepartmentId</td>
                            <td>dep.DepartmentName</td>
                            <td>
                                
                                /* >>>>>>EDIT BUTTON<<<<<< */
                                <button type="button" className="btn btn-light mr-1" data-bs-toggle="modal" data-bs-target="#exampleModal" onClick=() => editClick(dep)>
                                </button>

                                /* >>>>>>>DELETE BUTTON<<<<<<<<<<< */
                                <button type="button" className="btn btn-light mr-1" onClick=() => deleteClick(dep.DepartmentId)>
                                </button>

                            </td>
                        </tr>
                        )
                </tbody>
            </table>

            <div className="modal fade" id="exampleModal" tabIndex="-1" aria-hidden="true">
                <div className="modal-dialog modal-lg modal-dialog-centered">
                    <div className="modal-content">
                        <div className="modal-header">
                            <h5 className="modal-title">values.modalTitle</h5>

                            <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close">
                            </button>

                        </div>

                        <div className="modal-body">
                            <div className="input-group mb-3">
                                <span className="input-group-text">Department Name</span>
                                <input name = 'departmentName' type="text" className="form-control" value=values.departmentName onChange=(e) => changeDepartmentName(e) />
                            </div>

                            values.departmentId == 0 ?
                                <button type="button" className="btn btn-primary float-start" onClick=() => createClick()>Create</button> :
                                null
                            

                            values.departmentId != 0 ?
                                <button type="button" className="btn btn-primary float-start" onClick=() => updateClick()>Edit</button> :
                                null
                            

                        </div>

                    </div>
                </div>
            </div>

        </div>
    )


export default Department

【问题讨论】:

如果您创建了一个可运行的代码 sn-p 来重现您所看到的问题,这将有所帮助。 @SerhiiHolinei 很抱歉,但我不知道该怎么做,但如果有帮助,这里是代码的 github 链接github.com/naveednaseer/delete_later/blob/master/frontend/src/… 谢谢 @SerhiiHolinei 我添加了另一个仅包含相关代码的部分 【参考方案1】:

我认为您遇到的问题与您在更改状态后立即调用 filterFn 的事实有关:

let changeDepartmentNameFilter = (e) => 
    console.log(e.target.value)
    setValues(...values, 'departmentNameFilter': e.target.value)
    filterFn()

departmentNameFilter 不会同步更新。这意味着filterFn() 将被调用之前的状态。

有不同的方法来解决您的问题。例如,您可以将要过滤的值传递给 filterFn(newState) 并将其用作参数:



let filterFn = (newValues) =>
    let departmentIdFilter = newValues.departmentIdFilter
    let departmentNameFilter = newValues.departmentNameFilter


    let filteredData = filteredDepartment.filter(
        function(el)
            return el.DepartmentId.toString().toLowerCase().includes(
                departmentIdFilter.toString().trim().toLowerCase()
            ) &&
            el.DepartmentName.toString().toLowerCase().includes(
                departmentNameFilter.toString().trim().toLowerCase()
            )

        
    )
    setDepartment(filteredData)


let changeDepartmentNameFilter = (e) => 
    console.log(e.target.value)
    const newValues = ...values, 'departmentNameFilter': e.target.value;
    setValues(newValues)
    filterFn(newValues)



或者您可以使用useMemo 挂钩在每次值更改时过滤数组:

const filteredDepartment = useMemo(() =>
    let departmentIdFilter = values.departmentIdFilter
    let departmentNameFilter = values.departmentNameFilter

    // Note, I renamed filteredDepartment to department
    return department.filter(
        function(el)
            return el.DepartmentId.toString().toLowerCase().includes(
                departmentIdFilter.toString().trim().toLowerCase()
            ) &&
            el.DepartmentName.toString().toLowerCase().includes(
                departmentNameFilter.toString().trim().toLowerCase()
            )

        
    )

, [values, department]

【讨论】:

哇,我已经尝试修复它好几个小时了,终于修复了,非常感谢你真的帮助了很多人,你真棒,谢谢 @naveed 不客气,伙计 :)

以上是关于过滤器功能(过滤器)的第一次更改不会触发 onChange [重复]的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS:$watch不会因对象数组的更改而被触发

React页面不会在url查询更改时重新呈现

ngmodel 更改时未触发角度日期过滤器

如果使用 useEffect 更改了另一个过滤器,则重置为第一页

从 Google 工作表过滤器添加的新行上的另一个邮件合并触发器

在 CollectionViewSource 上触发过滤器