简体   繁体   English

React.js setState 没有通知

[英]React.js setState not not notifying

I'm trying to make a simple todo list with React.js and I'm stuck with this problem.我正在尝试使用 React.js 制作一个简单的待办事项列表,但我遇到了这个问题。 todo.isChecked is seting the state, but the new style determined by it doesn't notify just after clicking on the checkbox, but if I type something in the input text. todo.isChecked正在设置 state,但由它确定的新样式不会在单击复选框后立即通知,但如果我在输入文本中键入内容。

import React from 'react';

import 'bootstrap/dist/css/bootstrap.min.css';
import 'jquery';
import 'bootstrap/dist/js/bootstrap';

import TodoItem from './todoItem'

export default class todoApp extends React.Component{
    constructor() {
        super()
        this.state = {
            todos: [],
            task: ''
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleText = this.handleText.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
    }

    handleChange(id) {
        const todos = this.state.todos
        todos.map( todo => todo.id === id ? todo.isChecked === false ? todo.isChecked = true : todo.isChecked = false : null )
        console.log(this.state.todos)
     }

    handleText(event){
        this.setState( {task: event.target.value} )
    }

    handleSubmit(event){
        event.preventDefault()
        const task = this.state.task.trim()
        if (task.length > 0){
            const id = Math.random().toString(36).substr(2, 9)
            const newTask = { task: task, isChecked: false, id: id }
            const todos = this.state.todos
            todos.push(newTask)
            this.setState({ 
                todos: todos,
                task: ''
            })
        }
    }

    render(){
        const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item} handleChange={this.handleChange}/>)

        return(
        <div class="card bg-dark shadow-lg p-3 mb-5 rounded" style={{width: '18rem'}}>
            <form onSubmit={ this.handleSubmit } id="form">
                <input 
                    type="text" onChange={ this.handleText } 
                    value={ this.state.task } placeholder="New Task" 
                />
                <input type="submit" />
            </form>
            <ul class="list-group list-group-flush">
                <li class="list-group-item bg-dark">{todoItems}</li>
            </ul>
        </div>
        )
    }
}

todoItem.js: todoItem.js:

import React from 'react'

export default function TodoItem(props) {
    const isCheckedStyle = {
        fontstyle: "italic",
        color: "#adad85",
        textDecoration:"line-through"
    }

    return(
        <div>
            <input 
                type="checkbox" 
                onChange={() => props.handleChange(props.item.id)}
            />
            <p style={props.item.isChecked ? isCheckedStyle : null} >{props.item.task}</p>
        </div>
    )
}
 handleChange(id) {
        const todos = this.state.todos
        todos.map( todo => todo.id === id ? todo.isChecked === false ? todo.isChecked = true : todo.isChecked = false : null )
        console.log(this.state.todos)
     }

Your're directly modifying the todo.isChecked without setState .您正在直接修改todo.isChecked而没有setState When you do so, React doesn't have a way to know the state is changed and re-render has to take place.当您这样做时,React 无法知道 state 已更改并且必须重新渲染。 So instead modify using setSate()所以改为使用setSate()

In both handleChange and handleSubmit you mutating state outside setState , which is illegal in React, on handleChange you haven't even called setState , so just change it to (and so on handleSubmit )handleChangehandleSubmit ,你在setState之外改变 state ,这在 React 中是非法的,在handleChange上你甚至没有调用setState ,所以只需将其更改为(等等handleSubmit

 handleChange(id) {
        const todos = [...this.state.todos].map( todo => todo.id === id ? { ...todo, isChecked: !todo.isChecked } : todo ) // adding [...  ] for shallow copy and not pointing
        this.setState({todos})
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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