我目前正在创建一个包含每行中客户信息的表。最后一列标题为“删除”,单击时应触发删除行。每行都有一个显示“是”的按钮,当您单击它时,它将变为“确认”,最后一次点击将触发删除。目前我设置它的方式,它按我想要的方式工作但是当你点击其中一个按钮时,所有按钮都执行相同的操作;因此,在这种情况下,如果单击一个按钮,则所有这些按钮都将更改为“确认”,而不是仅更改该特定行的按钮。
我知道这是因为我没有唯一的标识符/索引,所以它改变了每个按钮的状态。我目前正在传递索引,但我不确定如何使用它。我不确定如何完成我需要的东西,并且不喜欢任何关于如何改变特定行的状态的建议。需要有button color
,button text
,first_click
和second_click
的初始状态,然后当客户点击该行的按钮时,状态将会发生变化。以下是需要更改为特定每行的整体理想行为的代码片段。
设置初始状态:
constructor(props) {
super(props);
this.state = {
buttonColor: "#FD8F83",
buttonText: "Yes",
first_click: false,
second_click: false,
};
}
点击时设置状态:
handleClick(i) {
if (this.state.first_click === false) {
console.log("first click");
this.setState({
buttonColor: "#A4D87C",
buttonText: "Confirm?",
first_click: true
});
} else if (this.state.first_click === true && this.state.second_click === false) {
console.log("second click");
this.setState({
second_click: true,
});
} else {
console.log("third or more click");
}
}
App的渲染功能返回的部分内容:
<tbody>
{this.props.initialCustomers.map((customer, index) => {
return (
<Customer
name={customer.customer}
fb_un={customer.fbun}
em_un={customer.emun}
key={customer._id}
id={customer._id}
handleClick={function() {this.handleClick(index)}.bind(this)}
buttonColor={this.state.buttonColor}
buttonText={this.state.buttonText}
first_click={this.state.first_click}
second_click={this.state.second_click}
/>
);
})
}
</tbody>
如果这很明显我道歉,我是React的新手。
在我在Team Treehouse上执行的单独项目中,我们使用this.state.players[index].score += delta;
和this.setState(this.state);
设置了州。但是,当我在这个项目中使用类似的方法(例如,this.state.buttonColor = "A4D87C"
)时,我得到以下错误。我也尝试了许多其他的在线工作,无法让它工作,如果它有用,我可以发布我已经完成的工作,但我不确定它是否有用。
不要直接改变状态。使用setState() 反应/无直接突变状态
任何帮助将不胜感激!如果我能提供任何其他信息,请告诉我。谢谢!
答案 0 :(得分:0)
我没有看到你正在运行的玩家循环,但它可能会被解决...
替换:
this.state.players[index].score += delta;
this.setState(this.state);
使用:
let { players } = this.state;
players[index].score += delta;
this.setState({ players });
答案 1 :(得分:0)
使用lodash函数获得更好的空代码。 如果使用immutableJs管理状态会更好。
这是达到你想要的一种方式。
import cloneDeep from 'lodash/cloneDeep';
// Cloning players.
const players = cloneDeep(this.state.players);
// Updating its values.
players[index].score += delta;
// setting the state with the new cloned players
this.setState({
players
})
答案 2 :(得分:0)
你应该创建一个组件ButtonRow。 每一行,都有自己的内部状态获得自己的按钮。
class ButtonRow extends React.Component {
constructor() {
super()
this.state = {
state: 0; // 0: display 'Yes'; 1: display Confirm
}
}
removeRow = () => {
if(this.state.state === 1) {
this.props.deleteRow(this.props.index);
}
else {
const currentState = this.state.state;
this.setState({state: currentState + 1});
}
};
render() {
const differentDisplay = ['Yes','Confirm'];
<button onClick={ () => this.props.removeRow() }>
{differentDisplay[this.state.state]}
</button>
}
};
在组件Customer中调用ButtonComponent并提供remove函数和与该行对应的数组的索引。
答案 3 :(得分:0)
根据@Leeroy_Wonkledge的评论,我能够让这个工作。下面是我的ButtonRow组件的样子。
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class ButtonRow extends Component {
constructor(props) {
super(props);
this.state = {
buttonColor: "#FD8F83",
button: 0
};
}
deleteRow = (i) => {
console.log("delete row", i);
}
removeRow = (i) => {
if(this.state.button === 1) {
const currentState = this.state.button;
this.setState({
button: currentState + 1
});
this.deleteRow(this.props.index);
}
else if (this.state.button === 0) {
const currentState = this.state.button;
this.setState({
button: currentState + 1,
buttonColor: "#A4D87C",
});
}
};
render() {
const differentDisplay = ['Yes','Confirm'];
return (
<button
style={{backgroundColor: this.state.buttonColor}}
onClick={ () => this.removeRow() }>
{differentDisplay[this.state.button]}
</button>
);
}
}
ButtonRow.propTypes = {
index: PropTypes.number.isRequired
};
export default ButtonRow;