我正在尝试与react的孩子一起进行父级交流,我传递了三个具有唯一ID的按钮,我想在单击增量按钮后简单地显示值。第一次单击时,每个按钮的确可以增加,但是,在第二次单击任何按钮后,它会给出
无法读取未定义的属性“值”
。我不确定第一次点击后会发生什么。
let data = [
{id: 1, value: 85},
{id: 2, value: 0},
{id: 3, value: 0}
]
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 1,
data: this.props.data
}
}
componentWillReceiveProps(nextProps) {
if(nextProps !== this.state.data) {
this.setState({data: nextProps})
}
}
handleClick(id) {
this.props.increment(id,
this.state.data[id-1].value = this.state.data[id-1].value +
this.state.counter);
}
render() {
return (
<div>
{data.map(data => {
return (
<div key={data.id}>
{data.value}
<button onClick={() => this.handleClick(data.id)}>+</button>
</div>
)
})}
</div>
)
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
data
}
}
onIncrement(id, newValue) {
this.setState((state) => ({
data: state.data[id-1].value = newValue
}))
}
render() {
return (
<div>
<Counter data={this.state.data} increment={this.onIncrement.bind(this)}/>
</div>
)
}
}
ReactDOM.render(
<App />,
document.querySelector("#root")
)
答案 0 :(得分:1)
这句话:
this.props.increment(id,
this.state.data[id-1].value = this.state.data[id-1].value +
this.state.counter);
您正在做id-1
,我想您不需要[id]
。
如果您单击ID为1的按钮,则您正尝试递增1 - 1
的值,而没有id 0
答案 1 :(得分:1)
您的代码中有问题的是此行
this.state.data[id-1].value = this.state.data[id-1].value + this.state.counter);
您到底想在这里做什么?因为您有3个索引0,1,2,而索引不足,所以它是未定义的,并且您在此处错误提及您的要求。
您的代码以无用的方式使用状态,我只是以一种很好的方式优化了您的代码。 提示:不要在不需要使用功能组件的情况下使用全状态组件。效果很好,可以根据您的需要提供服务。
const Counter = (props) => {
return (
<div>
{props.data.map(d => {
return (
<div key={d.id}>
{d.value}
<button onClick={() => props.increment(d.id, (d.value + 1))}>+</button>
</div>
)
})}
</div>
)
}
class App extends React.Component {
state = {
data: [
{ id: 1, value: 85 },
{ id: 2, value: 0 },
{ id: 3, value: 0 }
]
}
onIncrement = (id, newValue) => {
debugger
var newdata = [...this.state.data];
var d = { ...newdata[id - 1] };
d.value = newValue;
newdata[id - 1] = d;
this.setState({ data: newdata })
}
render() {
return (
<div>
<Counter data={this.state.data} increment={this.onIncrement} />
</div>
)
}
}
ReactDOM.render(
<App />,
document.querySelector("#root")
)
答案 2 :(得分:0)
import React from 'react';
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 1,
data: this.props.data
};
}
handleClick(id, index) {
this.props.increment(
id,
(this.props.data[id - 1].value =
this.props.data[id - 1].value + this.state.counter), index
);
}
render() {
return (
<div>
{this.props.data.map((data
, index) => {
return (
<div key={data.id}>
{data.value}
<button onClick={() => this.handleClick(data.id, index)}>+</button>
</div>
);
})}
</div>
);
}
}
export default class App extends React.Component {
constructor() {
super();
this.state = {
data: [{ id: 1, value: 85 }, { id: 2, value: 0 }, { id: 3, value: 0 }]
};
}
onIncrement(id, newValue, index) {
let {data} = this.state;
data[index].value = newValue;
this.setState({
data
});
}
render() {
console.log(this.state.data)
return (
<div>
<Counter
data={this.state.data}
increment={this.onIncrement.bind(this)}
/>
</div>
);
}
}
请看看您使用错误的方式进行状态更新
答案 3 :(得分:0)
我发现了问题,您错误地实现了componentWillReceiveProps
和onIncrement
,我已经更正了这两个功能:
onIncrement(id, newValue) {
let data = this.state.data;
data[id-1].value = newValue;
this.setState({data})
}
componentWillReceiveProps(nextProps) {
if(nextProps.data !== this.props.data) {
this.setState({data: nextProps.data})
}
}
另请参见工作示例:https://repl.it/@VikashSingh1/TemporalReliableLanserver