[英]Clicking on a child element calls a parent event listener in React
我正在做一個搜索輸入,人們可以在其中尋找技能,然后從選項中選擇一項技能。 但是,當我單擊任何選項時,它會調用父元素的事件偵聽器( onBlur={() => setIsFocus(false)}
)。 當我刪除此事件偵聽器時,它會添加一項新技能,但當它存在時,它不會運行附加到子元素的 function。
我嘗試將e.stopPropagtion()
添加到子元素中,但沒有用。
我的代碼:
import { useRef, useState } from "react"
import fetchSkills from "../api"
import BaseInput from "../components/reusable/BaseInput"
import SkillsSuggestionList from "../components/solutions/SkillsSuggestionList"
import Icons from "../components/SvgIcons/Icons"
import { debounce } from "../utils/shared"
const SKILLS = [
{ name: "html" },
{ name: "css" },
{ name: "javascript" },
{ name: "bootstrap" },
{ name: "tailwind-css" },
{ name: "react" },
{ name: "vue" },
{ name: "angular" },
]
const SolutionForm = () => {
const [skills, setSkills] = useState([])
const [isFocus, setIsFocus] = useState(false)
const selectRef = useRef(null)
// fetch skills and render them in a SkillsSuggestionList component
const handleSelectChange = async (e) => {
const { value } = e.target
if (value.length > 2) {
const result = await fetchSkills(value)
setSkills(result.items)
}
}
const addSkill = (skill) => {
setData({
...data,
skills: [...data.skills, skill],
})
setIsFocus(false)
setSkills([])
selectRef.current.value = ""
}
return (
<div>
<div>
<form onSubmit={handleSubmit}>
<div
key={input.name}
onBlur={() => setIsFocus(false)} // this is a parent event listener
>
<div
key={input.name}
>
<ul>
{data.skills.map((skill, index) => (
<li key={index}>
{skill}
</li>
))}
</ul>
<BaseInput
onChange={debounce(handleSelectChange, 500)}
onFocus={() => setIsFocus(true)}
name={input.name}
innerRef={selectRef}
/>
</div>
{isFocus && (
<SkillsSuggestionList
skills={skills.length > 0 ? skills : SKILLS}
addSkill={addSkill}
/>
)}
</div>
</form>
</div>
</div>
)
}
export default SolutionForm
技能建議列表組件:
const SkillsSuggestionList = ({ skills, addSkill }) => {
return (
<ul
id="skills"
>
{skills.map((skill) => (
<li
onClick={(e) => { // this is a child event listener
e.stopPropagation()
addSkill(skill.name)
}}
key={skill.name}
>
{skill.name}
</li>
))}
</ul>
)
}
export default SkillsSuggestionList
使用 onMouseDown 而不是 onClick 就可以了。
{skills.map((skill) => (
<li
onMouseDown={(e) => { // this is a child event listener
// e.stopPropagation() <--- this won't be needed
addSkill(skill.name)
}}
key={skill.name}
>
{skill.name}
</li>
))}
另外,讓我解釋一下為什么這里需要 onMouseDown 。 當您單擊列表時,在 onClick 運行之前它會變模糊並且 function 不再可用。 因此,當您使用 onMouseDown 時,它會首先運行 addSkill function 然后對其進行模糊處理。 希望它會起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.