[英]React Click Counter: Updating State of just one element
This should be pretty simple, but I can't figure out how to do it.这应该很简单,但我不知道该怎么做。
I have a component with multiple buttons, each with a "count" value, set with state. When a user clicks, the count goes up.我有一个包含多个按钮的组件,每个按钮都有一个“计数”值,设置为 state。当用户单击时,计数会增加。
Right now, when I click one of the buttons, both counters change.现在,当我单击其中一个按钮时,两个计数器都会发生变化。 How can I make it so only the div that was clicked updates, using the same state?我怎样才能使用相同的 state 只更新被点击的 div?
Edit: I don't want to have different counts, as I'd like for this component to render buttons dynamically.编辑:我不想有不同的计数,因为我希望这个组件动态呈现按钮。 What if I don't know how many buttons I'll have at first?如果我一开始不知道有多少个按钮怎么办?
class Block extends React.Component {
state = {
count: 0
};
handleClick = e => {
const count = this.state.count;
this.setState({ count: count + 1 });
};
render() {
return (
<div>
<button className="block" onClick={this.handleClick}>
<div className="counter">{this.state.count}</div>
</button>
<button className="block" onClick={this.handleClick}>
<div className="counter">{this.state.count}</div>
</button>
</div>
);
}
}
This is more of an issue of learning how to think in react.这更像是一个学习如何在反应中思考的问题。
If you need to be able to reuse a piece of functionality like a counter, you can make it its own component and have it manage its own state.如果您需要能够重用诸如计数器之类的功能,您可以使其成为自己的组件并让它管理自己的状态。 Then you can reuse it wherever you need.然后您可以在任何需要的地方重复使用它。
Here's an example:下面是一个例子:
class Counter extends React.Component { state = { count: 0 }; handleClick = () => { // Use updater function when new state is derived from old this.setState(prev => ({ count: prev.count + 1 })); }; render() { return ( <button className="block" onClick={this.handleClick}> <div className="counter">{this.state.count}</div> </button> ); } } // Now you can use it dynamically like this: class Block extends React.Component { render() { return ( <div> <div>There are 4 counter component instances that each manage their own state.</div> {[1,2,3,4].map(v => <Counter />)} </div> ); } } ReactDOM.render(<Block />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>
If your buttons are dynamic you can set your state to be an array and update the relevant index如果您的按钮是动态的,您可以将状态设置为数组并更新相关索引
class Block extends React.Component {
state = [];
handleClick = index => {
this.setState(state => {
const newState = [...state]; //keep state immutable
!newState[index] && (newState[index] = 0)
newState[index]++
return newState
});
};
render() {
return (
<div>
{[1,2,3].map((value, index) => <button className="block" onClick={() => this.handleClick(index)}>
<div className="counter">{this.state[index]}</div>
</button>)}
</div>
);
}
}
you should define two state and when press each button update the current state and you can render the current state in the dome like this你应该定义两个状态,当按下每个按钮时更新当前状态,你可以像这样在圆顶中渲染当前状态
state = {
firstCount: 0,
secondCount: 0
}
and write your action (function) to handle update state like this并编写您的操作(函数)来处理这样的更新状态
handleUpdateCount = stateName => {
this.setState({
[stateName]= this.state[stateName] + 1
})
}
then you should called this function like this =>那么你应该像这样调用这个函数 =>
this.handleUpdateCount('firstCount')
You have to use another value to update function when new state is derived from old state (like increment)当新的 state 派生自旧的 state(如增量)时,您必须使用另一个值来更新 function
import React, { Component } from 'react' export class Ref3 extends Component { constructor(props) { super(props) this.state = { count:0 } } //use prevState to help you update the old value to a new one clickHandler=()=>{ this.setState((prevState=>({ count:prevState.count+1 }))) } render() { return ( <div> <button onClick={this.clickHandler}>Click To Count</button> {this.state.count} </div> ) } } export default Ref3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.