ReactJS鼠标悬停/移动效果仅应用于一个列表项而不是所有列表项

6
我是一名React新手,所以这可能看起来很简单,或者不是,我不确定。我正在构建一个基本的待办事项清单。我想在列表项上添加鼠标悬停效果,弹出“删除此项”的文本。但是目前我的代码,当我将鼠标悬停在列表项上时,“删除此项”会弹出所有列表项,而不仅仅是其中一个。
当我尝试通过为每个列表项创建一个新组件来解决这个问题时,似乎并没有起作用。非常感谢任何帮助!
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')); 
1个回答

5
我会创建一个任务组件。你不想在ListView组件中设置文本的状态,因为这样this.state.text将被映射中的每个任务共享。每个任务应该知道自己的悬停状态,而不是其他子元素的悬停状态。
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>
    );
  }
}

1
非常感谢!在我努力理解React的过程中,您的帮助很大。 - bfoley_teamug
感谢您上周的帮助。过去一周,我一直在尝试弄清楚如何在 React 中通过单击来删除列表项。以下是我目前的代码,但没有任何效果。我怀疑问题出在第 95 行:https://codepen.io/bfoley650/pen/mKPgdE?editors=0011 - bfoley_teamug
@bfoley_teamug,我喜欢你的工作态度,干得漂亮!所以,你现在非常接近了。就像你把addTask处理程序从TodosContainer传递给AddTodo组件一样,你必须把removeTask从TodosContainer传递到ShowList组件中。但是,一旦在那里,你必须向下再传递一级,从ShowList组件到Task本身。绑定后,在构造函数中,你的操作可以传递给任意数量的子项,并且能够修改父状态。这是带有更改的codepen代码:https://codepen.io/anon/pen/RJRRdP?editors=0011 - Trevor
非常感谢,真的非常感激。 - bfoley_teamug
你能告诉我145行的代码key={todo-${key}-${todo}}是什么意思吗?非常感谢你的帮助! - bfoley_teamug
当你在迭代数组时,最好的做法是在映射或行中唯一地标识每个列表项。然而,仅使用数组索引并不是很有帮助,因为该键不是非常独特的,如果对数组进行排序,则键将保持不变。所以这是一种为列表项提供额外独特和特定标识符的方法。如果您删除它,这可能仍然可以正常工作,但这只是一个最佳实践,有时会导致问题。如果从映射元素中排除唯一键,React会发出警告。 - Trevor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接