在用户提交我的表单后,handleSubmit
函数会运行并计算我的 li
中显示所有搜索结果的类名包含“show”的 div
元素的数量。它将这些计数与 setStoreCount(prevCount => prevCount + 1)
相加,然后我更新了我的 FAQ {searchCount}
UI,显示搜索结果的数量
useEffect(() => {
setSearchCount(storeCount) // collect all storeCount
}, [storeCount])
问题:假设第一次搜索得到 5 个结果。
然后 UI 将显示 FAQ 5
。如果您再次搜索相同的内容,您仍然会得到 5 个结果,并且希望 UI 仍然显示 FAQ 5
,但由于 storeCount
无法重置为 0
,因此它显示 FAQ 10
( 5 + 5) 然后 FAQ 15
(5 + 5 + 5) 等等。
因为每当 storeCount
更改时我的 useEffect 都会有条件地运行,所以我无法将其重置为 0,因为那样我将始终显示 FAQ 0
。
如何在刷新下面代码中每次搜索的计数的同时显示搜索结果的数量?
import React, { useState, useRef, useEffect } from 'react'
import ContentsWrap from '../../components/contents-wrap'
import FrequentList from './tabs/frequent'
import EstimateList from './tabs/estimate'
import ReturnList from './tabs/return'
import EtcList from './tabs/etc'
import SubsidiaryList from './tabs/subsidiary'
import ServiceList from './tabs/service'
import InList from './tabs/in'
import OutList from './tabs/out'
import styles from './index.module.scss'
export default function FAQ () {
const [tab, setTab] = useState('frequent')
const [storeText, setStoreText] = useState('') // stores searchbar text as user types
const [searchText, setSearchText] = useState('') // sends searchbar text to List component props on form submit
const [storeCount, setStoreCount] = useState(0) // stores count of each li element className that includes 'show'
const [searchCount, setSearchCount] = useState(0) // shows search count in UI
const searchContainer = useRef(null)
const handleSubmit = e => {
e.preventDefault()
setSearchText(storeText)
setTab('all')
setTimeout(() => {
// gets all <ul> children of <div class = "faq-list-wrap">
for (let i = 0; i < searchContainer.current.children.length; i++) {
// gets all <li> children of each <ul>
for (let j = 0; j < searchContainer.current.children[i].children.length; j++) {
// checks if each li class name has 'show'
if (searchContainer.current.children[i].children[j].className.includes('show')) {
console.log('count added')
setStoreCount(prevCount => prevCount + 1)
}
}
}
}, 100) // setTimeOut needed to target searchContainer after search and not before
}
const handleChange = newId => {
setTab(newId)
setStoreText('') // clear input value on tab click
setSearchText('') // show all search items on tab click
}
useEffect(() => {
setSearchCount(storeCount) // collect all storeCount
}, [storeCount])
return (
<ContentsWrap>
<div className="content-wrap content-width">
{/* <!-- S: faq-wrap --> */}
<div className="faq-wrap">
<div className="faq-title-wrap"><h2 className="title">FAQ {searchCount}</h2></div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Search"
className={styles.searchBox}
value={storeText}
onChange={e => {
setStoreText(e.target.value)
}}
/>
</form>
{/* <!-- S: faq-list-wrap --> */}
<div className="faq-list-wrap" ref={searchContainer} >
{tab === 'all' && (
<>
<FrequentList searchText={searchText} />
<EstimateList searchText={searchText} />
<ReturnList searchText={searchText} />
<EtcList searchText={searchText} />
<SubsidiaryList searchText={searchText} />
<ServiceList searchText={searchText} />
<InList searchText={searchText} />
<OutList searchText={searchText} />
</>
)}
{tab === 'frequent' && (
<FrequentList searchText={searchText}/>
)}
{tab === 'estimate' && (
<EstimateList searchText={searchText}/>
)}
{tab === 'return' && (
<ReturnList searchText={searchText} />
)}
{tab === 'subsidiary' && (
<SubsidiaryList searchText={searchText} />
)}
{tab === 'service' && (
<ServiceList searchText={searchText} />
)}
{tab === 'in' && (
<InList searchText={searchText} />
)}
{tab === 'out' && (
<OutList searchText={searchText} />
)}
{tab === 'etc' && (
<EtcList searchText={searchText} />
)}
</div>
{/* <!-- E: faq-list-wrap --> */}
</div>
{/* <!-- E: faq-wrap --> */}
</div>
</ContentsWrap>
)
}
答案 0 :(得分:1)
这里的问题在于您的 setStoreCount
逻辑。
在您的 for
循环中的这一行:
if (searchContainer.current.children[i].children[j].className.includes('show')) {
console.log('count added')
setStoreCount(prevCount => prevCount + 1)
}
它将 1 添加到 prevCount
表示如果 prevCount
是 5(这是第一次搜索的结果数,它会添加 1,依此类推。
您可以做的是在添加找到的元素数量之前重置 storeCount
。像这样:
setTimeout(() => {
setStoreCount(0)
// gets all <ul> children of <div class = "faq-list-wrap">
for (let i = 0; i < searchContainer.current.children.length; i++) {
// gets all <li> children of each <ul>
for (let j = 0; j < searchContainer.current.children[i].children.length; j++) {
// checks if each li class name has 'show'
if (searchContainer.current.children[i].children[j].className.includes('show')) {
console.log('count added')
setStoreCount(prevCount => prevCount + 1)
}
}
}
}, 100) // setTimeOut needed to target searchContainer after search and not before
但这可能使它像,它在循环后显示 FAQ 0
然后剩余的计数。所以我建议在设置计数之前先计数,就像这样。
setTimeout(() => {
let count = 0
// gets all <ul> children of <div class = "faq-list-wrap">
for (let i = 0; i < searchContainer.current.children.length; i++) {
// gets all <li> children of each <ul>
for (let j = 0; j < searchContainer.current.children[i].children.length; j++) {
// checks if each li class name has 'show'
if (searchContainer.current.children[i].children[j].className.includes('show')) {
console.log('count added')
count++
}
}
}
setStoreCount(count)
}, 100) // setTimeOut needed to target searchContainer after search and not before
答案 1 :(得分:1)
您的循环只是不断地增加 storeCount。您应该在循环开始时在零处启动一个计数器,然后使用 setStoreCount 将计数器的最终值分配给您的 storeCount。