1 回答
TA贡献1895条经验 获得超3个赞
问题是onClick处理程序的当前类型签名基本上声明参数event本身是一个函数。要纠正这个问题,您只想使用事件本身的类型:
<ListGroup id="riskQuestion-1">
<ListGroup.Item
action
onClick={(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) =>
handleInput(setRiskAnswer1, 5, event)
}
>
I was great!
</ListGroup.Item>
<ListGroup.Item
action
onClick={(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) =>
handleInput(setRiskAnswer2, 3, event)
}
>
I did good but can be better
</ListGroup.Item>
</ListGroup>
事实上,由于您不想访问仅在元素上找到的属性<a>,您可以让类型默认为最广泛的类型:Element,这样您就可以省略泛型。它在这里的原因HTMLAnchorElement是ListGroup.Item带有一个action呈现链接 - 使用浏览器的开发人员工具的 DOM 检查器查看生成的 HTML。你会看到<a>那里。虽然它可以是任何东西,实际上你可以通过asprop指定它。
<ListGroup id="riskQuestion-1">
<ListGroup.Item
action
onClick={(event: React.MouseEvent) =>
handleInput(setRiskAnswer1, 5, event)
}
>
I was great!
</ListGroup.Item>
<ListGroup.Item
action
onClick={(event: React.MouseEvent) =>
handleInput(setRiskAnswer2, 3, event)
}
>
I did good but can be better
</ListGroup.Item>
</ListGroup>
要解决你的第二个问题,function handleInput({answerHandler, value, event}:InputParams)是一个接受一个参数的函数,该参数是具有这些属性的对象。但是,您handleInput使用三个单独的参数进行调用,因此它应该是:
function handleInput(
answerHandler: React.Dispatch<React.SetStateAction<number | null>>,
value: number,
event: React.MouseEvent
)
由于您不在此处使用功能更新,因此您可以摆脱以下问题:
function handleInput(
answerHandler: (answer: number | null) => void,
value: number,
event: React.MouseEvent
)
解决这些问题后,更多问题出现在handleInput. 第一个是 thatevent.target可能不是一个元素,因此它的类型没有.parentNode. 在这种情况下,最好使用.currentTarget. 另请参阅javascript 中的 currentTarget 属性和 target 属性之间的确切区别是什么。
修改后的函数为:
function handleInput(
answerHandler: (answer: number | null) => void,
value: number,
event: React.MouseEvent
) {
event.preventDefault();
const parentEl = event.currentTarget.parentNode;
const parentId = parentEl.getAttribute("id");
if (parentId) {
const el = document.getElementById(parentId);
if (el) {
for (let i = 0; i < el.children.length; i++) {
if (el.children[i].classList.contains("selected")) {
el.children[i].classList.remove("selected");
}
}
}
}
event.currentTarget.classList.add("selected");
answerHandler(value);
}
但是,唉,又出现了一个错误。这次是因为parentNode是类型Node。实际上有很多节点类型,“元素”只是其中之一!但显然,您实际上对父元素感兴趣,因此通过更改parentNode为parentElement,函数编译:
function handleInput(
answerHandler: (answer: number | null) => void,
value: number,
event: React.MouseEvent
) {
event.preventDefault();
const parentEl = event.currentTarget.parentElement;
const parentId = parentEl.getAttribute("id");
if (parentId) {
const el = document.getElementById(parentId);
if (el) {
for (let i = 0; i < el.children.length; i++) {
if (el.children[i].classList.contains("selected")) {
el.children[i].classList.remove("selected");
}
}
}
}
event.currentTarget.classList.add("selected");
answerHandler(value);
}
作为结束语,我只是一般性地说,这种直接的 DOM 操作在 React 世界中非常粗略,并且在大多数情况下可以而且应该用 React 来实现。
添加回答
举报