Javascript 正在尝试为各个待办事项设置状态,并让它们在单击时保持并在3种颜色之间切换

Javascript 正在尝试为各个待办事项设置状态,并让它们在单击时保持并在3种颜色之间切换,javascript,reactjs,Javascript,Reactjs,它们还必须在删除(并因此重新排列)项目后保持其颜色。 目前,一切正常,但当我点击每个项目时,什么都没有发生 我已经花了20多个小时试图让它工作,我最近的一次尝试是让它完美工作,而不是在我删除一个项目后,删除项目下面的项目呈现出删除项目的颜色。从那以后,我对代码做了很多修改,但现在我完全搞不懂为什么它不更新颜色。出于某种原因,它没有使它通过handleClick()中的第一个条件,即使条件为true(据我所知) 这真的很困扰我,在这一点上成为我进步的障碍,因为它太分散我的注意力了。请帮忙 我注册s

它们还必须在删除(并因此重新排列)项目后保持其颜色。 目前,一切正常,但当我点击每个项目时,什么都没有发生

我已经花了20多个小时试图让它工作,我最近的一次尝试是让它完美工作,而不是在我删除一个项目后,删除项目下面的项目呈现出删除项目的颜色。从那以后,我对代码做了很多修改,但现在我完全搞不懂为什么它不更新颜色。出于某种原因,它没有使它通过handleClick()中的第一个条件,即使条件为true(据我所知)

这真的很困扰我,在这一点上成为我进步的障碍,因为它太分散我的注意力了。请帮忙

我注册stackOverflow就是为了这个问题(也许是许多问题中的第一个)

以下是理解我做错了什么所需的所有代码。如果有人请求,我可以提供到我的回购的github链接

import React, { Component } from 'react'
import './App.css'
import Header from './components/layout/Header'

class App extends Component {
  state = {
    todos: [
      {
        id: 1,
        title: 'click me',
        status: 'red',
      },
    ],
    input: '',
    counter: 2,
  }

  onChange = (event) => {
    this.setState({ input: event.target.value })
  }

  onSubmit = (event) => {
    event.preventDefault()
    this.setState({
      todos: [
        ...this.state.todos,
        {
          title: this.state.input,
          id: this.state.counter,
          status: 'red',
        },
      ],
      input: '',
      counter: this.state.counter + 1,
    })
  }

  removeItem = (id) => {
    this.setState({
      todos: [...this.state.todos.filter((x, i) => i !== id)],
    })
  }

  handleClick = (e) => {
    this.setState({
      todos: this.state.todos.map((todo) => {
        if (todo.status === 'red' && todo.id === e.currentTarget.value) {
          todo.status = 'yellow'
        } else if (
          todo.status === 'yellow' &&
          todo.id === e.currentTarget.value
        ) {
          todo.status = 'green'
        } else if (
          todo.status === 'green' &&
          todo.id === e.currentTarget.value
        ) {
          todo.status = 'red'
        }
        return todo
      }),
    })
  }

  render() {
    return (
      <div className="App">
        <Header />
        <form style={{ display: 'flex' }} onSubmit={this.onSubmit}>
          <input
            type="text"
            name="title"
            style={{ flex: '10', padding: '5px' }}
            placeholder="Add Todo ..."
            value={this.state.input}
            onChange={this.onChange}
          />
          <input
            type="submit"
            value="Submit"
            className="btn"
            style={{ flex: '1' }}
          />
        </form>

        <ul>
          {this.state.todos.map((todo, idx) => {
            return (
              <li key={todo.id}>
                <span
                  onClick={(e) => this.handleClick(e)}
                  style={{ color: todo.status }}
                  value={todo.id}
                  id={idx}
                >
                  {todo.title}
                </span>
                <span>
                  <button onClick={() => this.removeItem(idx)}>X</button>
                </span>
              </li>
            )
          })}
        </ul>
      </div>
    )
  }
}

export default App
import React,{Component}来自“React”
导入“./App.css”
从“./components/layout/Header”导入标题
类应用程序扩展组件{
状态={
待办事项:[
{
id:1,
标题:“点击我”,
状态:“红色”,
},
],
输入:“”,
柜台:2,,
}
onChange=(事件)=>{
this.setState({input:event.target.value})
}
onSubmit=(事件)=>{
event.preventDefault()
这是我的国家({
待办事项:[
…这个。州。待办事项,
{
标题:this.state.input,
id:this.state.counter,
状态:“红色”,
},
],
输入:“”,
计数器:this.state.counter+1,
})
}
removeItem=(id)=>{
这是我的国家({
todos:[…this.state.todos.filter((x,i)=>i!==id)],
})
}
handleClick=(e)=>{
这是我的国家({
todos:this.state.todos.map((todo)=>{
if(todo.status=='red'&&todo.id==e.currentTarget.value){
todo.status='黄色'
}否则如果(
todo.status==“黄色”&&
todo.id==e.currentTarget.value
) {
todo.status='绿色'
}否则如果(
todo.status==“绿色”&&
todo.id==e.currentTarget.value
) {
todo.status='红色'
}
返回待办事项
}),
})
}
render(){
返回(
    {this.state.todos.map((todo,idx)=>{ 返回(
  • this.handleClick(e)} style={{color:todo.status}} 值={todo.id} id={idx} > {todo.title} this.removietem(idx)}>X
  • ) })}
) } } 导出默认应用程序
以下是解决我问题的代码:


import React, { Component } from 'react'
import './App.css'
import Header from './components/layout/Header'

class App extends Component {
  state = {
    todos: [
      {
        id: 1,
        title: 'click me',
        status: 'red',
      },
    ],
    input: '',
    counter: 2,
  }

  onChange = (event) => {
    this.setState({ input: event.target.value })
  }

  onSubmit = (event) => {
    event.preventDefault()
    this.setState({
      todos: [
        ...this.state.todos,
        {
          title: this.state.input,
          id: this.state.counter,
          status: 'red',
        },
      ],
      input: '',
      counter: this.state.counter + 1,
    })
  }

  removeItem = (id) => {
    this.setState({
      todos: [...this.state.todos.filter((x, i) => i !== id)],
    })
  }

  handleClick = (todo) => {
    if (todo.status === 'red') {
      console.log('clicked!')
      todo.status = 'yellow'
    } else if (todo.status === 'yellow') {
      todo.status = 'green'
    } else if (todo.status === 'green') {
      todo.status = 'red'
    }
    console.log(todo.status)

    this.setState({ todos: this.state.todos })
  }

  render() {
    return (
      <div className="App">
        <Header />
        <form style={{ display: 'flex' }} onSubmit={this.onSubmit}>
          <input
            type="text"
            name="title"
            style={{ flex: '10', padding: '5px' }}
            placeholder="Add Todo ..."
            value={this.state.input}
            onChange={this.onChange}
          />
          <input
            type="submit"
            value="Submit"
            className="btn"
            style={{ flex: '1' }}
          />
        </form>

        <ul>
          {this.state.todos.map((todo, idx) => {
            return (
              <li key={todo.id}>
                <span
                  onClick={(e) => this.handleClick(todo)}
                  style={{ color: todo.status }}
                  value={todo.id}
                  id={idx}
                >
                  {todo.title}
                </span>
                <span>
                  <button onClick={() => this.removeItem(idx)}>X</button>
                </span>
              </li>
            )
          })}
        </ul>
      </div>
    )
  }
}

export default App


从“React”导入React,{Component}
导入“./App.css”
从“./components/layout/Header”导入标题
类应用程序扩展组件{
状态={
待办事项:[
{
id:1,
标题:“点击我”,
状态:“红色”,
},
],
输入:“”,
柜台:2,,
}
onChange=(事件)=>{
this.setState({input:event.target.value})
}
onSubmit=(事件)=>{
event.preventDefault()
这是我的国家({
待办事项:[
…这个。州。待办事项,
{
标题:this.state.input,
id:this.state.counter,
状态:“红色”,
},
],
输入:“”,
计数器:this.state.counter+1,
})
}
removeItem=(id)=>{
这是我的国家({
todos:[…this.state.todos.filter((x,i)=>i!==id)],
})
}
handleClick=(待办事项)=>{
如果(todo.status=='red'){
console.log('clicked!')
todo.status='黄色'
}else if(todo.status==='yellow'){
todo.status='绿色'
}else if(todo.status==='green'){
todo.status='红色'
}
console.log(todo.status)
this.setState({todos:this.state.todos})
}
render(){
返回(
    {this.state.todos.map((todo,idx)=>{ 返回(
  • 这个.handleClick(todo)} style={{color:todo.status}} 值={todo.id} id={idx} > {todo.title} this.removietem(idx)}>X
  • ) })}
) } } 导出默认应用程序
我能让一个有经验的程序员带我完成它。我成功地在所有3种颜色之间切换
状态
变量,但我没有用setState更新状态,因此它没有被跟踪。我没有意识到我不允许react在eventListener结束时跟踪状态更改


非常感谢您这么快的回复!希望我的无知能帮助其他人。

你确定
e.currentTarget.value
返回给你的是正确的东西吗?我也要小心,你把
todo.id
idx
混在一起了。在任何地方使用您的键,不要使用索引值;考虑一下如果你重新排列你的列表会发生什么。这也可能是因为你在修改<代码>的原始值。map < /代码>,反应不是拾取对象已经改变,因此不会导致重新渲染。尝试
返回{…todo,状态:'yellow'}
而不是
todo.status='yellow'