reactjs - NextJS Button 通过 React 的 useState 不断单击自身
问题描述
我正在使用 nextjs 和 firebase 制作评论系统,但是当页面加载/用户在文本框中键入内容时,按钮“单击”本身并将文本框的当前值发送到 firestore
然后firestore会被垃圾邮件发送到
h
he
hey
我怀疑这是因为 useState,但我不确定我能做什么
这是我的代码中涉及useState的部分:
const submitComment = (doc, name, text) => {
firebase.firestore().collection('blogs').doc(doc).update({
comments: firebase.firestore.FieldValue.arrayUnion(
{
name: name,
date: new Date().toString(),
text: text
}
)
})
}
export default function Feedback(props) {
const [state, setState] = useState({
liked: false,
comment: "",
name: ""
})
const toggleLike = () => setState({ ...state, liked: !state.liked })
const commentHandler = (e) => setState({ ...state, comment: e.target.value })
const nameHandler = (e) => setState({ ...state, name: e.target.value })
return (
<>
<div className={styles.container}>
<table className={styles.input} role="presentation">
<tbody>
<tr>
<td rowSpan="2">
<Textarea
id="text"
status="secondary" width="100%"
placeholder="Comments!"
onChange={commentHandler}
/>
</td>
<td>
<Input
id="name"
className={styles.name}
width="100%" height="100%" status="secondary"
placeholder="Name"
onChange={nameHandler}
/>
</td>
</tr>
<tr>
<td>
<Button width="150%" type="secondary" ghost
onClick={submitComment(props.post, state.comment, state.comment)}
>submit</Button>
</td>
</tr>
</tbody>
</table>
</div>
</>
)
}
解决方案
如果不深入研究上下文和this
javascript 中的绑定,问题就出在您的onClick
处理程序中。有几种方法可以解决它,但要点是你需要有一个函数来在处理 DOM 元素上的事件时调用你的更新/提交函数。
这个想法是你绑定一个函数来处理事件,然后在事件发生时调用你的函数。
一种方法是创建一个内联匿名函数:
onClick={() => submitComment(props.post, state.comment, state.comment)}
我个人更喜欢将此逻辑保留在组件主体之外,因此我会将其向上移动到您的业务逻辑的其余部分附近:
// ev is the click event
const submitComment = (ev) => {
// You can read from state & props here
firebase.firestore().collection('blogs').doc(props.post).update({
comments: firebase.firestore.FieldValue.arrayUnion({
name: state.name,
date: new Date().toString(),
text: state.comment
})
})
}
// Later...
<button onClick={ submitComment }>Submit</button>
与点击问题完全无关,而且在您调用的代码中:
const toggleLike = () => setState({ ...state, liked: !state.liked })
我只是想指出您可以使用当前状态setState
(例如切换喜欢的状态),但您应该从以前的状态中读取以确保您没有得到错误的值。这样做的原因是状态更改是批处理的,而不是立即触发的。因此,您要确保在更新之前读取之前的值(以防其他任何东西更新它):
const toggleLike = () => {
setState(prevState => { ...prevState, liked: !prevState.liked })
}
推荐阅读
- button - Google 登录按钮更改 Android Studio
- python - pyCharm 无法打开禁用“在工具窗口中显示绘图”的绘图 - 可能是由于阻塞
- .net-core - GtkSharp 的 .NET Core / 5.0 Nuget 库中是否有 Gdk.PangoRenderer 的实现?
- python - 如何解决 pip install 期间发生的身份验证过程
- azure - 备份 Azure 数据库时如何备份事务日志?
- macos - SwiftUI NavigationView 与 macOS 上的窗口内混合
- laravel - “AUTO_INCREMENT”的语法错误 - Laravel
- python - AttributeError:类型对象“CustomUser”没有属性“REQUIRED_FIELDS”
- python - 使用 Python 中的 PIL 库使图像中的蒙版区域透明
- java - Spark Java 将数据附加到 Hive 表