如何在 React 中一键重置多个计数器
How to reset multiple counters with one button in React
我的问题的 TLDR 是我的每个子组件都保留并显示自己的计数器点击。每次点击也会更新显示的 Total
。我想知道如何使用 Reset
按钮来重置这些子组件。
我有一个显示总数的应用程序、一些按钮(每个按钮以不同的方式增加总数)和一个重置按钮。 在这个小应用程序中,权重是一个包含不同权重对象的数组
class CountersContainer extends React.Component {
constructor(props) {
super(props)
this.state = {
total: 0,
}
this.resetTotal = this.resetTotal.bind(this)
this.updateTotalByWeights = this.updateTotalByWeights.bind(this)
}
resetTotal = () => {
this.setState({
total: 0,
})
}
updateTotalByWeights = value => {
this.setState({
total: this.state.total + value * 2,
})
}
render() {
return (
<>
<div className="container">
{weights.map(w => (
<Weight
key={w.kg}
incrementTotal={this.updateTotalByWeights}
weight={w.kg}
/>
))}
</div>
<button className="click-target" onClick={this.resetTotal}>
reset
</button>
<WeightOutput total={this.state.total} units={this.state.metric} />
</>
)
}
/=============
// The weight component
/=============
import React from "react"
const Weight = ({ incrementTotal, weight }) => {
return (
<div onClick={() => { incrementTotal(weight) }} >
{weight}
</div>
)
}
export default Weight
这很好用。我希望每个 Weight
组件都记录其被点击的次数。因此,如果 5kg
权重组件被单击两次,它将显示计数 2,同时以所需方式更新总数。所以我将以下内容添加到我的体重组件中:
import React, { useState } from "react"
const Weight = ({ incrementTotal, weight }) => {
const [count, setCount] = useState(0)
return (
<div
onClick={
() => {
incrementTotal(weight)
setCount(count + 1)
}
}
>
{count > 0 && <span>{count}</span>}
{weight}
</div>
)
}
export default Weight
这实现了总计正确递增和每次点击更新组件计数的预期结果。
但是,现在我需要更改重置按钮以重置每个权重组件 count
,我完全不知道如何处理这个问题。我考虑过的一些事情是强制每个权重重新渲染,使 "counts" 保持在层次结构的更上层。也许 "hook" 是这里错误的实现(这个小应用程序主要是为了适应钩子)。理想的答案将包括如何处理问题以及可能的解决方案。
notes: 我不确定上面的代码是否完美,我尝试去掉了与问题无关的部分。下面我添加了重量数据的样子,以防有人好奇。
export const weights = [
{
color: "red",
kg: 25,
lbs: 55,
},
{
color: "blue",
kg: 20,
lbs: 45,
},
// this goes on a while.
更新
我已经将体重组件更新为如下所示:
import React, { useState, useEffect } from "react"
const Weight = props => {
const [count, setCount] = useState(0)
useEffect(() => {
setCount(0)
}, [props.reset])
return (
<div
onClick={() => {
props.incrementTotal(props.weight)
setCount(count + 1)
}}
>
{count > 0 && <span>{count}</span>}
{props.weight}
</div>
)
}
export default Weight
并在我的重置 setState 函数中添加了 reset: 0
。这并没有解决我的问题,但根据 React Hook 文档,这似乎是一个很有前途的方向。
更新 2
我接受了下面的答案,因为它是正确的,尽管我没有完全理解它。为了实施以下解决方案,我必须更新 "reset" 值。我通过传递做到了这一点。
我不确定这是好的解决方案。我相信它正在重新渲染所有重量组件。这可能很糟糕,尤其是当有 1000 个复杂的组件时。
this.setState({
reset: !this.state.reset
})
只要您想重置计数器并使用具有依赖性的 useEffect
钩子作为该道具,您就可以将具有不同值的道具从父组件传递给 Weight
子组件。例如
class Parent extends React.Component {
state = { reset: Date.now() };
resetCounters = () => {
this.setState({ reset: Date.now() });
}
render () {
<div>
<button onClick={this.resetCounters} >Reset</button>
<Wieght reset={this.state.reset} {..some other props} />
<Wieght reset={this.state.reset} {..some other props} />
<Wieght reset={this.state.reset} {..some other props} />
<Wieght reset={this.state.reset} {..some other props} />
</div>
}
}
const Weight = props => {
const [counter, setCounter] = useState(0);
useEffect(() => {
setCounter(0);
}, [props.reset]);
}
另一种选择是将 reset
作为密钥传递给重量组件,这样,在更改密钥时,它将重新安装。这是一个简单的解决方案,但可能会导致大量权重组件出现性能问题
我的问题的 TLDR 是我的每个子组件都保留并显示自己的计数器点击。每次点击也会更新显示的 Total
。我想知道如何使用 Reset
按钮来重置这些子组件。
我有一个显示总数的应用程序、一些按钮(每个按钮以不同的方式增加总数)和一个重置按钮。 在这个小应用程序中,权重是一个包含不同权重对象的数组
class CountersContainer extends React.Component {
constructor(props) {
super(props)
this.state = {
total: 0,
}
this.resetTotal = this.resetTotal.bind(this)
this.updateTotalByWeights = this.updateTotalByWeights.bind(this)
}
resetTotal = () => {
this.setState({
total: 0,
})
}
updateTotalByWeights = value => {
this.setState({
total: this.state.total + value * 2,
})
}
render() {
return (
<>
<div className="container">
{weights.map(w => (
<Weight
key={w.kg}
incrementTotal={this.updateTotalByWeights}
weight={w.kg}
/>
))}
</div>
<button className="click-target" onClick={this.resetTotal}>
reset
</button>
<WeightOutput total={this.state.total} units={this.state.metric} />
</>
)
}
/=============
// The weight component
/=============
import React from "react"
const Weight = ({ incrementTotal, weight }) => {
return (
<div onClick={() => { incrementTotal(weight) }} >
{weight}
</div>
)
}
export default Weight
这很好用。我希望每个 Weight
组件都记录其被点击的次数。因此,如果 5kg
权重组件被单击两次,它将显示计数 2,同时以所需方式更新总数。所以我将以下内容添加到我的体重组件中:
import React, { useState } from "react"
const Weight = ({ incrementTotal, weight }) => {
const [count, setCount] = useState(0)
return (
<div
onClick={
() => {
incrementTotal(weight)
setCount(count + 1)
}
}
>
{count > 0 && <span>{count}</span>}
{weight}
</div>
)
}
export default Weight
这实现了总计正确递增和每次点击更新组件计数的预期结果。
但是,现在我需要更改重置按钮以重置每个权重组件 count
,我完全不知道如何处理这个问题。我考虑过的一些事情是强制每个权重重新渲染,使 "counts" 保持在层次结构的更上层。也许 "hook" 是这里错误的实现(这个小应用程序主要是为了适应钩子)。理想的答案将包括如何处理问题以及可能的解决方案。
notes: 我不确定上面的代码是否完美,我尝试去掉了与问题无关的部分。下面我添加了重量数据的样子,以防有人好奇。
export const weights = [
{
color: "red",
kg: 25,
lbs: 55,
},
{
color: "blue",
kg: 20,
lbs: 45,
},
// this goes on a while.
更新
我已经将体重组件更新为如下所示:
import React, { useState, useEffect } from "react"
const Weight = props => {
const [count, setCount] = useState(0)
useEffect(() => {
setCount(0)
}, [props.reset])
return (
<div
onClick={() => {
props.incrementTotal(props.weight)
setCount(count + 1)
}}
>
{count > 0 && <span>{count}</span>}
{props.weight}
</div>
)
}
export default Weight
并在我的重置 setState 函数中添加了 reset: 0
。这并没有解决我的问题,但根据 React Hook 文档,这似乎是一个很有前途的方向。
更新 2 我接受了下面的答案,因为它是正确的,尽管我没有完全理解它。为了实施以下解决方案,我必须更新 "reset" 值。我通过传递做到了这一点。
我不确定这是好的解决方案。我相信它正在重新渲染所有重量组件。这可能很糟糕,尤其是当有 1000 个复杂的组件时。
this.setState({
reset: !this.state.reset
})
只要您想重置计数器并使用具有依赖性的 useEffect
钩子作为该道具,您就可以将具有不同值的道具从父组件传递给 Weight
子组件。例如
class Parent extends React.Component {
state = { reset: Date.now() };
resetCounters = () => {
this.setState({ reset: Date.now() });
}
render () {
<div>
<button onClick={this.resetCounters} >Reset</button>
<Wieght reset={this.state.reset} {..some other props} />
<Wieght reset={this.state.reset} {..some other props} />
<Wieght reset={this.state.reset} {..some other props} />
<Wieght reset={this.state.reset} {..some other props} />
</div>
}
}
const Weight = props => {
const [counter, setCounter] = useState(0);
useEffect(() => {
setCounter(0);
}, [props.reset]);
}
另一种选择是将 reset
作为密钥传递给重量组件,这样,在更改密钥时,它将重新安装。这是一个简单的解决方案,但可能会导致大量权重组件出现性能问题