我知道这是一个简单的问题,但我是React的新手。
我错过了什么来获取我点击的值的索引?我只是想说,当用户点击删除时,从数组中删除该值。
<!DOCTYPE html>
<html>
<head>
<title>
React Practice
</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.js"></script>
</head>
<body>
<div id="app">
<!-- This element's contents will be replaced with your component. -->
</div>
<script type="text/babel">
var MainContainer = React.createClass({
getInitialState: function(){
return {
name: 'JK_MNO',
friends: [],
text: ''
}
},
handleChange: function(e){
this.setState({
text: e.target.value
});
},
handleSubmit: function(e){
e.preventDefault();
if(this.state.text !== '') {
var nextfriend = this.state.friends.concat([{
text: this.state.text, id: Date.now()
}]);
var nextText = '';
this.setState({
friends: nextfriend, text: nextText
});
}
},
handleDelete: function(e){
for (var i = this.state.friends.length - 1; i >= 0; i--) {
this.state.friends[i]
};
this.state.friends.splice(i, 1);
this.setState({
friends: this.state.friends
});
},
render: function(){
return (
<div>
<h3> Name: {this.state.name} </h3>
<ShowList friends={this.state.friends} handleDelete={this.handleDelete} />
<form onSubmit={this.handleSubmit} >
Enter Friends: <input className="friendInput" onChange={this.handleChange} value={this.state.text} />
</form>
</div>
);
}
});
var ShowList = React.createClass({
render: function() {
var createFriend = function(friend) {
return (
<li key={friend.id}>{friend.text} <button onClick={this.props.handleDelete}>Delete</button> </li>
);
};
return <ul>{this.props.friends.map(createFriend.bind(this))}</ul>;
}
});
ReactDOM.render(<MainContainer />, document.getElementById('app'));
</script>
答案 0 :(得分:2)
在数组上进行映射时,数组中正在考虑的当前项的索引是应用于为映射提供的闭包(函数)的第二个参数。
示例:
const arr = ['a', 'b', 'c', 'd'];
arr.map((item, index, arr) => {
console.log (item, index, arr);
});
//'a' 0 ['a', 'b', 'c', 'd']
//'b' 1 ['a', ...]
//'c' 2 [...]
//'d' 3 [...]
此外,映射的完整数组是第三个arg。
您可以向元素添加“数据索引”属性,然后在单击事件中引用它。
<li 'data-index'={index}>... <li>
handleDelete: function (e) {
const index = e.currentTarget.dataset.index;
//do what you need to delete
}
使用您的代码:
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
<script type="text/babel">
var MainContainer = React.createClass({
getInitialState: ...,
handleChange: ...,
handleSubmit: ...,
//Here's where you are trying to reference index of clicked element
handleDelete: function (e) {
//The event object 'e' contains a reference to the clicked
//element at property 'currentTarget'.
const clickedEl = e.currentTarget;
//Setting the 'data-[varname]' property when you create the
//element in the render method is a safe way to set custom
//properties you would like to access from a DOM element. Those props
//are then accessible via the 'dataset' property from the DOM element.
//Since we set 'data-index' below, we can find the index of the
//clicked element with clickedEl.dataset.index.
const clickedIndex = clickedEl.dataset.index;
//When using React, never act directly on properties of component
//state. Your previous code:
// this.state.friends.splice(i, 1);
//did that. Instead, make a copy of your state, make changes to
//that copy, and update state with that copy.
//Best practice is to try to keep your state as simple as possible,
//so consider refactoring to simplify your friends state so that it is
//not an array of objects. But, with current implementation
//one way might be something like this.
const friendsCopy = this.state.friends.map(friend => {
return {
id: friend.id,
text: friend.text,
...other properties of a friend
};
});
//You can splice out the clicked friend
//(or remove some other way)
friendsCopy.splice(clickedIndex, 1);
//Set state with copy
this.setState({
friends: friendsCopy
});
},
render: function(){
return (
<div>
...
</div>
);
}
});
var ShowList = React.createClass({
render: function() {
//Create friend is the closure you are providing
//to map function for friends. Set the second arg
//to index to reference the index of the friend being
//considered. You can then safely set a property of 'data-[varname]'
//on the element to reference index later. By preceding the
//var name with 'data-', you'll be able to reference the property
//later via a clean 'dataset' object without risking overwriting some
//important property on the DOM object called 'varname'. Here I'll use
//the varname 'index'.
var createFriend = function(friend, index) {
return (
<li key={friend.id}>{friend.text} <button 'data-index'={index} onClick={this.props.handleDelete}>Delete</button> </li>
);
};
return <ul>{this.props.friends.map(createFriend.bind(this))}</ul>;
}
});
ReactDOM.render(<MainContainer />, document.getElementById('app'));
</script>
希望能稍微清理一下。看起来你正试图在组件上的几个地方直接对this.state进行更改。避免这样做,而是习惯于复制状态 - >更改复制 - >更新状态。尝试阅读React文档,它们非常好。
答案 1 :(得分:0)
生成每个按钮时,您可以为该按钮的ID指定元素在数组中的相应索引。然后你的handleDelete函数必须检查点击的元素ID值,从数组中删除该元素。
这个问题实际上可能与how to remove an item from a list with a click event in ReactJS?
重复答案 2 :(得分:0)
使用map你可以生成你的组件,然后使用一些ES6语法糖,你可以将每个元素的索引传递给你的点击处理程序,如下所示:
handleDelete: function(e, i) {
e.preventDefault();
// Array manipulation
},
render: function() {
return (
<div>
<ul>
{this.state.users.map((user,i)=> <li onClick={(e) => this.handleDelete(e,i)}>{user}</li>)}
</ul>
</div>
)
}
答案 3 :(得分:0)
在努力获得以前的一些编译答案之后,我想出了这个简单的方法。
index
来自闭包函数,我正在映射数组。我使用数组的副本来避免更改它的当前状态。
这很有效。
<!DOCTYPE html>
<html>
<head>
<title>
React Practice: Friends List
</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.js"></script>
</head>
<body>
<div id="app">
<!-- This element's contents will be replaced with your component. -->
</div>
<script type="text/babel">
var MainContainer = React.createClass({
getInitialState: function(){
return {
name: 'JK_MNO',
friends: [],
text: ''
}
},
handleChange: function(e){
this.setState({
text: e.target.value
});
},
handleSubmit: function(e){
e.preventDefault();
if(this.state.text !== '') {
var nextfriend = this.state.friends.concat([{
text: this.state.text, id: Date.now()
}]);
var nextText = '';
this.setState({
friends: nextfriend, text: nextText
});
}
},
handleDelete: function(e){
var i = e.target.value;
var friendsCopy = this.state.friends;
this.setState(state => {
friendsCopy.splice(i, 1);
friends: friendsCopy
});
},
render: function(){
return (
<div>
<h3> Name: {this.state.name} </h3>
<ShowList friends={this.state.friends} handleDelete={this.handleDelete} />
<form onSubmit={this.handleSubmit} >
Enter Friends: <input className="friendInput" onChange={this.handleChange} value={this.state.text} />
</form>
</div>
);
}
});
var ShowList = React.createClass({
render: function() {
var createFriend = function(friend, index) {
return (
<li key={friend.id}>{friend.text} <button onClick={this.props.handleDelete} value={index}>Delete</button> </li>
);
};
return <ul>{this.props.friends.map(createFriend.bind(this))}</ul>;
}
});
ReactDOM.render(<MainContainer />, document.getElementById('app'));
</script>
</body>
</html>