在 React 中,对于一组按钮,如何在单击后更改颜色同时记录单击了哪个 button/buttons is/are?
in React for an array of buttons, how to change color after click while also record which button/buttons is/are clicked?
我有一个子组件,它是一个按钮,点击后颜色会随着状态更新而改变。但是,我还需要在一组这样的按钮中识别正在单击的按钮。 sandbox 或以下的代码。我该怎么做?如果我对子组件有操作,那么如何正确调用父组件的onclick?
button.js
import React, { Component } from 'react';
import './style.css'
class Button extends React.Component {
constructor(props){
super(props);
this.state = {
clicked: false
}
}
changeColor=()=>{
this.setState({clicked: !this.state.clicked})
}
render(){
let btn_class = this.state.clicked ? "redButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.changeColor.bind(this)}>
{this.props.name}
</button>
)
}
}
export default Button;
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import Button from './button.js'
const btns= ['button1','button2','button3']
const n = btns.length
class App extends Component {
constructor() {
super();
this.state = {
clickedBtn : "",
btnStyle: new Array(n)
};
}
handleClick= (index) =>
{
alert(index)
}
render() {
return (
<div>
{btns.map((btn, index) => (
<Button
name={btn}
onClick={this.handleClick.bind(this,index)}/>
))}
</div>
);
}
}
render(<App />, document.getElementById('root'));
您可以尝试类似的操作,最后您将在 clickedButton 对象中获得单击按钮值。
import React, { Component } from 'react';
import './style.css'
class Button extends React.Component {
constructor(props){
super(props);
this.state = {
clicked: false
}
}
changeColor=()=>{
this.setState({clicked: !this.state.clicked})
this.props.onButtonClick(this.props.index)
}
render(){
let btn_class = this.state.clicked ? "redButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.changeColor.bind(this)}>
{this.props.name}
</button>
)
}
}
export default Button;
index.js
class App extends Component {
constructor() {
super();
this.state = {
clickedBtn : {},
btnStyle: new Array(n)
};
}
handleClick= (index) =>
{
let clickedBtn = this.state.clickedBtn
if(clickedBtn[index]){
delete clickedBtn[index]
} else{
clickedBtn[index]= true
}
}
render() {
return (
<div>
{btns.map((btn, index) => (
<Button
name={btn}
index={index}
onButtonClick={this.handleClick}/>
))}
</div>
);
}
}
render(<App />, document.getElementById('root'));
您可以为此使用通用处理函数。现在也没有理由将方法绑定到 class - 如果您使用箭头函数来定义您的代码,则不再需要这样做方法。
最后,您可能应该使用 setState
提供的回调来调用 Button
组件内的 onClick
属性。
更多关于setState
回调:你使用回调的方式是这样的:
setState({ some: "newState"}, function() { /* this is the callback function */ })
使用setState
回调:
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
clicked: false
};
}
handleClick = event => {
this.setState({
clicked: !this.state.clicked
}, () => { // Should prob use the callback that setState provides
if (this.props.onClick) this.props.onClick()
});
};
render() {
let btn_class = this.state.clicked ? "redButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.handleClick}>
{this.props.name}
</button>
);
}
}
const btns= ['button1','button2','button3']
const n = btns.length
class App extends React.Component {
constructor() {
super();
this.state = {
clickedBtn: "",
btnStyle: new Array(n)
};
}
handleClick = index => {
alert(index);
};
render() {
console.log(this.state.clickedTag);
return (
<div>
{btns.map((btn, index) => (
<Button name={btn} onClick={() => this.handleClick(index)} />
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
h1, p {
font-family: Lato;
}
.whiteButton{
background-color: white
}
.redButton{
background-color: red
}
<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>
不使用 setState
回调:
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
clicked: false
};
}
handleClick = event => {
this.setState({
clicked: !this.state.clicked
});
if (this.props.onClick) this.props.onClick()
};
render() {
let btn_class = this.state.clicked ? "redButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.handleClick}>
{this.props.name}
</button>
);
}
}
const btns= ['button1','button2','button3']
const n = btns.length
class App extends React.Component {
constructor() {
super();
this.state = {
clickedBtn: "",
btnStyle: new Array(n)
};
}
handleClick = index => {
alert(index);
};
render() {
console.log(this.state.clickedTag);
return (
<div>
{btns.map((btn, index) => (
<Button name={btn} onClick={() => this.handleClick(index)} />
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
h1, p {
font-family: Lato;
}
.whiteButton{
background-color: white
}
.redButton{
background-color: red
}
<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>
我有一个子组件,它是一个按钮,点击后颜色会随着状态更新而改变。但是,我还需要在一组这样的按钮中识别正在单击的按钮。 sandbox 或以下的代码。我该怎么做?如果我对子组件有操作,那么如何正确调用父组件的onclick?
button.js
import React, { Component } from 'react';
import './style.css'
class Button extends React.Component {
constructor(props){
super(props);
this.state = {
clicked: false
}
}
changeColor=()=>{
this.setState({clicked: !this.state.clicked})
}
render(){
let btn_class = this.state.clicked ? "redButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.changeColor.bind(this)}>
{this.props.name}
</button>
)
}
}
export default Button;
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import Button from './button.js'
const btns= ['button1','button2','button3']
const n = btns.length
class App extends Component {
constructor() {
super();
this.state = {
clickedBtn : "",
btnStyle: new Array(n)
};
}
handleClick= (index) =>
{
alert(index)
}
render() {
return (
<div>
{btns.map((btn, index) => (
<Button
name={btn}
onClick={this.handleClick.bind(this,index)}/>
))}
</div>
);
}
}
render(<App />, document.getElementById('root'));
您可以尝试类似的操作,最后您将在 clickedButton 对象中获得单击按钮值。
import React, { Component } from 'react';
import './style.css'
class Button extends React.Component {
constructor(props){
super(props);
this.state = {
clicked: false
}
}
changeColor=()=>{
this.setState({clicked: !this.state.clicked})
this.props.onButtonClick(this.props.index)
}
render(){
let btn_class = this.state.clicked ? "redButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.changeColor.bind(this)}>
{this.props.name}
</button>
)
}
}
export default Button;
index.js
class App extends Component {
constructor() {
super();
this.state = {
clickedBtn : {},
btnStyle: new Array(n)
};
}
handleClick= (index) =>
{
let clickedBtn = this.state.clickedBtn
if(clickedBtn[index]){
delete clickedBtn[index]
} else{
clickedBtn[index]= true
}
}
render() {
return (
<div>
{btns.map((btn, index) => (
<Button
name={btn}
index={index}
onButtonClick={this.handleClick}/>
))}
</div>
);
}
}
render(<App />, document.getElementById('root'));
您可以为此使用通用处理函数。现在也没有理由将方法绑定到 class - 如果您使用箭头函数来定义您的代码,则不再需要这样做方法。
最后,您可能应该使用 setState
提供的回调来调用 Button
组件内的 onClick
属性。
更多关于setState
回调:你使用回调的方式是这样的:
setState({ some: "newState"}, function() { /* this is the callback function */ })
使用setState
回调:
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
clicked: false
};
}
handleClick = event => {
this.setState({
clicked: !this.state.clicked
}, () => { // Should prob use the callback that setState provides
if (this.props.onClick) this.props.onClick()
});
};
render() {
let btn_class = this.state.clicked ? "redButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.handleClick}>
{this.props.name}
</button>
);
}
}
const btns= ['button1','button2','button3']
const n = btns.length
class App extends React.Component {
constructor() {
super();
this.state = {
clickedBtn: "",
btnStyle: new Array(n)
};
}
handleClick = index => {
alert(index);
};
render() {
console.log(this.state.clickedTag);
return (
<div>
{btns.map((btn, index) => (
<Button name={btn} onClick={() => this.handleClick(index)} />
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
h1, p {
font-family: Lato;
}
.whiteButton{
background-color: white
}
.redButton{
background-color: red
}
<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>
不使用 setState
回调:
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
clicked: false
};
}
handleClick = event => {
this.setState({
clicked: !this.state.clicked
});
if (this.props.onClick) this.props.onClick()
};
render() {
let btn_class = this.state.clicked ? "redButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.handleClick}>
{this.props.name}
</button>
);
}
}
const btns= ['button1','button2','button3']
const n = btns.length
class App extends React.Component {
constructor() {
super();
this.state = {
clickedBtn: "",
btnStyle: new Array(n)
};
}
handleClick = index => {
alert(index);
};
render() {
console.log(this.state.clickedTag);
return (
<div>
{btns.map((btn, index) => (
<Button name={btn} onClick={() => this.handleClick(index)} />
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
h1, p {
font-family: Lato;
}
.whiteButton{
background-color: white
}
.redButton{
background-color: red
}
<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>