我在React中创建“添加到收藏夹”按钮。当我单击一个图标时,该图标旁边的元素将添加到点赞数组。到目前为止,它仍在工作,但有时可能是由于SVG图标将空元素添加到了likes数组中。 90%的事件目标是“路径”,因此“ e.target.parentNode.parentNode.id;”效果很好。但是,如果在或上检测到事件,则该parentNode无效,它将向数组添加一个空元素。我该如何解决这个问题?
class App extends React.Component {
state = {
data: [
{
"breed": "Beagle",
"characteristic": "playful"
},
{
"breed": "Golden Retriever",
"characteristic": "calm"
},
{
"breed": "Corgi",
"characteristic": "bright"
},
{
"breed": "Goldendoodle",
"characteristic": "gentle"
},
{
"breed": "Labrador Retriever",
"characteristic": "loyal"
},
],
likes: []
}
handleClick = e => {
e.preventDefault();
const breed = e.target.parentNode.parentNode.id;
const index = this.state.likes.indexOf(breed);
if (index === -1) {
this.state.likes.push(breed);
this.renderLikes(this.state.likes);
} else {
this.state.likes.splice(index, 1);
this.renderLikes(this.state.likes);
}
}
likesTemplate = item => `<li>${item}</li>`;
renderLikes = () => {
this.refs.fav.innerHTML = this.state.likes.map(i => this.likesTemplate(i)).join('');
}
render() {
return (
<div>
<ul>
{this.state.data.map(index => {
return <li key={index.breed} id={index.breed}>
<IcoMoon icon="heart" onClick={this.handleClick} />{index.breed}</li>;
})}
</ul>
<h2>Favorite Dogs</h2>
<ul ref="fav">
</ul>
</div>
);
}
}
export default App;
答案 0 :(得分:2)
由于您已经将品种传递给列表项,因此最简单的方法是使用react而不是DOM来传递该品种:
...
handleClick = (e, breed) => {
e.preventDefault();
const index = this.state.likes.indexOf(breed);
if (index === -1) {
this.state.likes.push(breed);
this.renderLikes(this.state.likes);
} else {
this.state.likes.splice(index, 1);
this.renderLikes(this.state.likes);
}
}
likesTemplate = item => `<li>${item}</li>`;
renderLikes = () => {
this.refs.fav.innerHTML = this.state.likes.map(i => this.likesTemplate(i)).join('');
}
render() {
return (
<div>
<ul>
{this.state.data.map(index => {
return <li key={index.breed} id={index.breed}>
<IcoMoon icon="heart" onClick={(e) => this.handleClick(e, index.breed} />{index.breed}</li>;
})}
....
答案 1 :(得分:1)
将品种传递到您的handleClick
函数。
handleClick = (breed, index) => {
if (this.state.likes.filter(e => e.breed === breed.breed).length > 0) {
this.setState({
likes: this.state.likes.filter(e => e.breed !== breed.breed)
});
return;
}
this.setState({
likes: [...this.state.likes, breed]
});
};
likesTemplate = item => <li>{item.breed}</li>;
renderLikes = () => {
return this.state.likes.map(i => this.likesTemplate(i));
};
您的渲染方法
render() {
return (
<div>
<ul>
{this.state.data.map(item => {
return (
<li
key={item.breed}
id={item.breed}
>
<IcoMoon icon="heart" onClick={() => this.handleClick(item)}/>
{item.breed}
</li>
);
})}
</ul>
<h2>Favorite Dogs</h2>
<ul ref="fav">{this.renderLikes()}</ul>
</div>
);
}
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0-alpha.2/umd/react.production.min.js"></script>
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0-alpha.2/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
state = {
data: [
{
breed: "Beagle",
characteristic: "playful"
},
{
breed: "Golden Retriever",
characteristic: "calm"
},
{
breed: "Corgi",
characteristic: "bright"
},
{
breed: "Goldendoodle",
characteristic: "gentle"
},
{
breed: "Labrador Retriever",
characteristic: "loyal"
}
],
likes: []
};
handleClick = (breed, index) => {
if (this.state.likes.filter(e => e.breed === breed.breed).length > 0) {
this.setState({
likes: this.state.likes.filter(e => e.breed !== breed.breed)
});
return;
}
this.setState({
likes: [...this.state.likes, breed]
});
};
likesTemplate = item => <li>{item.breed}</li>;
renderLikes = () => {
return this.state.likes.map(i => this.likesTemplate(i));
};
render() {
return (
<div>
<ul>
{this.state.data.map((item, index) => {
return (
<li
key={item.breed}
onClick={() => this.handleClick(item, index)}
id={item.breed}
>
<div icon="heart" />
{item.breed}
</li>
);
})}
</ul>
<h2>Favorite Dogs</h2>
<ul ref="fav">{this.renderLikes()}</ul>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
</script>