NextJS Button 通过 React 的 useState 不断点击自己
NextJS Button keeps clicking itself by React's 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>
</>
)
}
你能试试在你的按钮上使用匿名回调吗:
onClick={() => submitComment(props.post, state.comment, state.comment)}
如果不深入研究上下文并在 javascript 中绑定 this
,问题出在您的 onClick
处理程序中。有几种方法可以解决它,但要点是在处理 DOM 元素上的事件时,您需要有一个调用 update/submit 函数的函数。
我们的想法是绑定一个函数来处理事件,事件发生时该函数将调用您的函数。
一种方法是创建一个内联匿名函数:
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
中使用当前状态(用于切换点赞之类的事情),但您应该阅读之前的状态以确保您没有得到一个坏的价值。这样做的原因是状态更改是分批处理的,而不是立即触发。所以你想确保你正在阅读以前的值 before 它被更新(以防其他任何东西正在更新它):
const toggleLike = () => {
setState(prevState => { ...prevState, liked: !prevState.liked })
}
我正在使用 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>
</>
)
}
你能试试在你的按钮上使用匿名回调吗:
onClick={() => submitComment(props.post, state.comment, state.comment)}
如果不深入研究上下文并在 javascript 中绑定 this
,问题出在您的 onClick
处理程序中。有几种方法可以解决它,但要点是在处理 DOM 元素上的事件时,您需要有一个调用 update/submit 函数的函数。
我们的想法是绑定一个函数来处理事件,事件发生时该函数将调用您的函数。
一种方法是创建一个内联匿名函数:
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
中使用当前状态(用于切换点赞之类的事情),但您应该阅读之前的状态以确保您没有得到一个坏的价值。这样做的原因是状态更改是分批处理的,而不是立即触发。所以你想确保你正在阅读以前的值 before 它被更新(以防其他任何东西正在更新它):
const toggleLike = () => {
setState(prevState => { ...prevState, liked: !prevState.liked })
}