Сделайте это просто для создания компонента списка в ReactJs:
for (var key in this.props.code_values)
{
var current = this.props.code_values[key];
var current_value = current.value;
drop_choices.push(<ListItem
button
key = { current.id }
onClick = {(event) => this.makeSomethingWithValue(current_value)}
>
{ current.value }
</ListItem>);
}
Проблема в том, что current_value вычисляется по Click, поэтому оно всегда будет равно последнему current_value итерации.
Например:
code_values = [ { id : 1, value : 1}, { id : 2, value : 2} ]
При нажатии на «1» вместо этого будет «2».
Мы не «создаем» html satic-код, а компонент, и OnClick не «создается» как атрибут во время этой итерации, а «обрабатывается» только после события onClick.
Это проблема области видимости с var, попробуйте вместо этого использовать let
и const
.
for (let key in this.props.code_values)
{
const current = this.props.code_values[key];
const current_value = current.value;
drop_choices.push(<ListItem
button
key = { current.id }
onClick = {(event) => this.makeSomethingWithValue(current_value)}
>
{ current.value }
</ListItem>);
}
Есть несколько альтернативных подходов к этому.
Function.prototype.bind
для привязки данных к обработчику событий. Как this.makeSomethingWithValue.bind(this, current_value)
.Array.prototype.map
для перебора имеющихся у вас данных и отображения их таким образом в вашем возврате, как показано ниже;.
return (
this.props.code_values.map(current => (
<ListItem
button
key = {current.id}
onClick = {(event) => this.makeSomethingWithValue(current.value)}
>
{ current.value }
</ListItem>
))
);
...
Вместо цикла вы должны подумать об использовании map
для лучшего определения переменных. Вы также можете рассмотреть возможность передачи значения в компонент как опору вместо аргумента функции.
Вот макет того, как я вижу остальную часть вашего кода:
class App extends React.Component {
constructor(props) {
super(props);
this.state = { data: props.data };
// bind `handleClick`
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
// take the value (textContent), coerce to a number and add 10 to it
console.info(+e.target.textContent + 10);
}
render() {
return (
<div>
<ul>
// `map` over the array in state
{this.state.data.map(current => {
return (
<ListItem
key = {current.id}
// pass in value, and the function to be called onClick
value = {current.value}
handleClick = {this.handleClick}
/>
)
})}
</ul>
</div>
)
}
}
function ListItem({ value, handleClick }) {
return <li onClick = {handleClick}>{value}</li>;
}
const data = [{ id: 1, value: 1}, { id: 2, value: 2}];
ReactDOM.render(
<App data = {data} />,
document.getElementById('container')
);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id = "container"></div>