React:添加了空元素(可能是由于SVG)

时间:2019-06-05 02:57:42

标签: reactjs

我在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;

2 个答案:

答案 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>