简体   繁体   中英

ReactJS hover/mouseover effect for one list item instead of all list items

I am a React novice, so this might seem really simple, or maybe it isn't, I'm not sure. I'm building a basic to-do list. I want a mouseover effect on list items to pop up "delete this" text. But for my code so far, when I mouseover a list item, "delete this" pops up for all list items instead of just the one.

When I tried solving this by creating a new component for individual list items, that didn't seem to work. Any help is much appreciated!

class ToDosContainer extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      heading: 'Something You Need To Do?',
      todos: [
        'wake up',
        'brush your teeth'
      ],
    }

    this.addToDo = this.addToDo.bind(this)
  }

  addToDo(todo) {
    this.setState((state) => ({
      todos: state.todos.concat([todo])
    }))
  }
  render() {
    return (
      <div>
        <h1>To Do List</h1>
        <h3>{this.state.heading}</h3>
        <AddToDo addNew={this.addToDo} />
        <ShowList tasks={this.state.todos} />
      </div>  
    )
  }
}

class AddToDo extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      newToDo: ''
    }

    this.updateNewToDo = this.updateNewToDo.bind(this)
    this.handleAddToDo = this.handleAddToDo.bind(this)

  }

  //I think I can delete this part
  updateNewToDo(e) {
    this.setState({
      newToDo: e.target.value
    })
  }
 //

  handleAddToDo() {
    this.props.addNew(this.state.newToDo)
    this.setState({
      newToDo: ''
    })
  }

  render() {
    return (
      <div>
        <input
          type="text"
          value={this.state.newToDo}
          onChange={this.updateNewToDo}
         />
        <button onClick={this.handleAddToDo}> Add To Do </button>
      </div>
    )
  }
}

class ShowList extends React.Component {

  constructor(props) {
    super(props)

    this.state = {
      newToDo: ''
    }
  }

  onMouseOver(e) { 
    this.setState({
      text: 'delete me'
    })
    console.log('hey')
  }

  onMouseOut(e) { 
     this.setState({
      text: ''
    })
     console.log('hey hey')

  }

  render() {
   const { text } = this.state;
   return (
    <div>
       <h4>To Do's</h4>
       <ul>
          {this.props.tasks.map((todo) => {
            return <li onMouseEnter={this.onMouseOver.bind(this)} onMouseLeave={this.onMouseOut.bind(this)}> {todo} {text}</li>
          })}
       </ul>
    </div>
   ) 
  }
}

ReactDOM.render(<ToDosContainer />, document.getElementById('helloworld')); 

I would make a Task component. You don't want to set the state of the text in the ListView component, because then this.state.text is shared by each task in the map. Each task should be aware of its own hover, and not the hover of the other children.

class Task extends React.Component {
  state = {
    text: ""
  };
  onMouseOver(e) {
    this.setState({
      text: "delete me"
    });
  }

  onMouseOut(e) {
    this.setState({
      text: ""
    });
  }

  render() {
    return (
      <li
        onMouseEnter={this.onMouseOver.bind(this)}
        onMouseLeave={this.onMouseOut.bind(this)}
      >
        {this.props.todo} {this.state.text}
      </li>
    );
  }
}


class ShowList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      newToDo: ""
    };
  }

  render() {
    const { text } = this.state;
    return (
      <div>
        <h4>To Do's</h4>
        <ul>
          {this.props.tasks.map(todo => {
            return <Task todo={todo} />;
          })}
        </ul>
      </div>
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM