我正在循环一个数组来呈现值。当我单击一个项目时,我需要获取值并设置状态。现在,无论我单击哪个元素,它都会将状态设置为数组中最后一个元素的值。
我认为问题可能是我在调用onClick时使用箭头函数。jslint 还强调了在这样的循环中调用函数的不良做法。
您可以单击任何值,状态将在底部字符串化。任何帮助将不胜感激。
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
currentValue: null,
}
}
getValue = (valueToGet) => {
this.setState({
currentValue: valueToGet,
})
};
render() {
const Values = {
valuesList: [{
value: 'value one'
},{
value: 'value two',
},{
value: 'value three',
}
]
};
var renderValues = [];
var valuesList = Values.valuesList;
for(var i=0; i < valuesList.length; i++) {
var valueItem = valuesList[i];
renderValues.push(
<div
onClick={() => this.getValue(valueItem.value)}
key={i}
>
<p>{valueItem.value}</p>
</div>
)
}
return (
<div>
{renderValues}
{JSON.stringify(this.state.currentValue)}
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector("#app"))
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
}
p {
padding-bottom: 50px;
}
<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="app"></div>
您可以使用map
来迭代数组,而不是传统的for
循环。
renderValues = Values.valuesList.map((valueItem,i) => {
return <div
onClick={() => this.getValue(valueItem.value)}
key={i}
>
<p>{valueItem.value}</p>
</div>
})
演示
您指出问题出在循环中创建的函数是绝对正确的。当您在循环中定义函数时,正在创建一个闭包,并且闭包中传递的最后一个值是第三个值,该值为所有 onClick 函数显示。
详细的解释可以在这里找到
循环中的箭头函数不是问题,但包含不安全的变量valueItem
才是问题。
对变量使用let
而不是var
valueItem
可使代码正常工作。
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
currentValue: null,
}
}
getValue = (valueToGet) => {
this.setState({
currentValue: valueToGet,
})
};
render() {
const Values = {
valuesList: [{
value: 'value one'
},{
value: 'value two',
},{
value: 'value three',
}
]
};
var renderValues = [];
var valuesList = Values.valuesList;
for(var i=0; i < valuesList.length; i++) {
let valueItem = valuesList[i];
renderValues.push(
<div
onClick={() => this.getValue(valueItem.value)}
key={i}
>
<p>{valueItem.value}</p>
</div>
)
}
return (
<div>
{renderValues}
{JSON.stringify(this.state.currentValue)}
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector("#app"))
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
}
p {
padding-bottom: 50px;
}
<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="app"></div>