Удалить отредактированный ввод и обновить его в текущем вводе - PullRequest
0 голосов
/ 01 сентября 2018

Извините, если мой вопрос не объяснен должным образом, я довольно новичок в реакции и мне нужна помощь от вас, ребята, Спасибо. Чтобы объяснить это подробно, мое состояние редактирования обновляется отлично, но проблема в том, что когда я пытаюсь удалить его, он удаляет последнее добавленное значение. Я знаю, что нужно обновить состояние по нажатию кнопки удаления, но я не знаю, как ... Небольшая помощь будет полезна. Это весь код. Пожалуйста, дайте мне знать, где я ошибся, и дайте решение для этого. app.js

import React, { Component } from 'react';
import Input from './input_bar';
import TaskList from './tasklist';

export default class App extends Component {

    constructor(props){
        super(props);
        this.state={
            inputValue:"",
            todos: [
                {value: 'Clean the room', done: false},
                {value: 'Wake up early', done:true}
            ],
            check:true,
            isHidden: true
        }
        this.onInputChange=this.onInputChange.bind(this);
        this.onSubmit=this.onSubmit.bind(this);
        this.onCheckClick=this.onCheckClick.bind(this);
        this.onDeleteClick=this.onDeleteClick.bind(this);
        this.onClearCompleted=this.onClearCompleted.bind(this);
        this.onCheckUncheckAll=this.onCheckUncheckAll.bind(this);
        this.noOfItems=this.noOfItems.bind(this);
    }

    onInputChange(event){
        this.setState({inputValue: event.target.value});
    }

    onSubmit(event){
        event.preventDefault();
        const newTodo ={
            value:this.state.inputValue,
            done:false
        };
        const todos = this.state.todos;
        todos.push(newTodo);
        this.setState({todos, inputValue:''})
    }

    onCheckClick(index){
        const todos= this.state.todos;
        todos[index].done= !todos[index].done;
        this.noOfItems();
        this.setState({todos})
    }

    onDeleteClick(index){
        const todos=this.state.todos;
        todos.splice(index,1);
        this.setState({todos});
    }

    onClearCompleted(){
        const todos=this.state.todos;

        for( let i = 0 ; i < todos.length; i++){
            if ( todos[i].done === true) {
                todos.splice(i, 1);
                i=i-1;
            }
        }
        this.setState({todos});
    }

    onCheckUncheckAll(){
        const todos= this.state.todos;
        for( let i = 0 ; i < todos.length; i++){
            todos[i].done= this.state.check;
            this.setState({check: !this.state.check});
        }
        this.setState({todos});
    }

    noOfItems(){
        const todos=this.state.todos;
        let itemsLeft = todos.length;
        for( let i = 0 ; i < todos.length; i++) {
            if (todos[i].done === true) {
                itemsLeft = itemsLeft - 1;
            }
        }
        return(itemsLeft);
    }

    render() {
     return (
       <div>

          <Input
              onInputChange={this.onInputChange}
              inputValue={this.state.inputValue}
              onSubmit={this.onSubmit}
              onCheckUncheckAll={this.onCheckUncheckAll}
          />

          <TaskList
              onCheckClick={this.onCheckClick}
              onDeleteClick={this.onDeleteClick}
              onClearCompleted={this.onClearCompleted}
              noOfItems={this.noOfItems}
              todos={this.state.todos}
          />

       </div>
     );
    }
}

input_bar.js

import React from 'react';

export default class Input extends React.Component{


    render(){
        return(
            <div className="Form">
                <button onClick={this.props.onCheckUncheckAll} className="CheckUncheck">
                    <i className="fa fa-angle-down"/>
                </button>
                <form onSubmit={this.props.onSubmit}>
                    <input
                        value={this.props.inputValue}
                        onChange={this.props.onInputChange}
                        className="toggle-all"
                        placeholder="What needs to be done?"
                    />
                </form>
            </div>
        );
    }
}

tasklist.js

import React from 'react';
import TaskListItem from './tasklistitems';

export default class TaskList extends React.Component{

    render(){
        return(
            <div className="List">
                {this.props.todos.map((todo, index) => {
                    return(
                        <TaskListItem
                            key={index}
                            index={index}
                            todo={todo}
                            onCheckClick={this.props.onCheckClick}
                            onDeleteClick={this.props.onDeleteClick}
                            noOfItems={this.props.noOfItems}
                        />
                    );
                })}
                <span>  {this.props.noOfItems()} items left </span>
                <a onClick={this.props.onClearCompleted} className="clearCompleted">Clear Completed</a>
            </div>
        );
    }
}

tasklistitems.js

import React from 'react';
import Ionicon from 'react-ionicons'

export default class TaskListItem extends React.Component{
    constructor(props){
        super(props);
        this.state={
            edit: false,
            currentValue: this.props.todo.value
        }

    }

    tick(){
        return(
                <Ionicon icon="ios-radio-button-off" fontSize="25px" color="#EDEDED"/>
        )
    }

    untick(){
        return(
                <Ionicon icon="ios-checkmark-circle-outline" fontSize="25px" color="#57C1AF"/>
        )
    }

    onEdit(event){
        this.setState({edit: true, currentValue: this.state.currentValue});
    }

    onEditDone(event){
        if(event.keyCode===13){
            //console.log(this.state.currentValue);
            this.setState({edit:false});
            this.props.todo.value= this.state.currentValue;
        }
    }

    onEditChange(event) {
        let _currentValue = event.target.value;
        //console.log("currentvalue",this.state.currentValue);
        this.setState({currentValue: _currentValue});
    }

    // onDeleteChange(){
    //
    //     // ----------------- What should I put here ---------------//
    //
    //
    // }

    render(){
        //console.log(this.state.currentValue);
        const viewStyle={};
        const editStyle={};

        if(this.state.edit){
            viewStyle.display= 'none';
        }else{
            editStyle.display='none';
        }

        return(
            <div>
                <div style={viewStyle}>
                    <div className="Task row" >
                        <div className="col-md-2">
                            <button onClick={()=>this.props.onCheckClick(this.props.index)}>
                                {this.props.todo.done ? this.untick():this.tick() }
                            </button>
                        </div>
                        <span >
                            <div className="col-md-9" onDoubleClick={this.onEdit.bind(this)}>
                                <span style={{color:this.props.todo.done ?'#e6e6e6' : '#4d4d4d',
                                    textDecoration: this.props.todo.done ? '#e6e6e6 line-through' : 'none',
                                    transition: 'text-decoration 0.5s, color 0.5s'
                                }}
                                >
                                    {this.state.currentValue}
                                </span>
                            </div>
                        </span>
                        <div className="col-md-1">
                            <button onClick={()=>this.props.onDeleteClick(this.props.index)} onMouseDown={onDeleteChange.bind(this)} className="destroy">
                                x
                            </button>
                        </div>
                    </div>
                </div>

                <input type="text"
                       onChange={this.onEditChange.bind(this)}
                       onKeyDown={this.onEditDone.bind(this)}
                       style={editStyle}
                       value={this.state.currentValue}/>
            </div>
        );
    }
}

1 Ответ

0 голосов
/ 01 сентября 2018

ТЛ; др:
Вам не нужно управлять currentValue в состоянии <TaskListItem/>. Вы должны использовать this.props.todo.value вместо этого. Вот исправление

в деталях:
Эта ошибка вызвана тем, что в компоненте <TaskListItem /> вы используете опору todo.value, чтобы установить текущее значение элемента в конструкторе компонента (currentValue: this.props.todo.value), и используете этот атрибут состояния для рендеринга. это значение ({this.state.currentValue}).

Поскольку это значение динамически передается в качестве реквизита родительскими компонентами при изменении этого значения (например, при удалении элемента), это приводит к тому, что значение не изменяется, когда новое значение передается компоненту через подпорки, поскольку оно получает его из внутреннего состояния (которое не обновляется каждый раз при изменении значений реквизита).

Другими словами. Вам нужно изменить источник истины для этого значения с состояния на реквизит. Ваш единственный источник истины для данных todos (их значения value и done) должен быть родительским компонентом приложения.

Я приказываю исправить эту проблему, вам нужно использовать значение из реквизита ({this.props.todo.value}) в методе рендеринга <TaskListItem /> вместо значения из состояния ({this.state.currentValue} )

Вот фиксированная примерная версия вашего приложения

(я комментировал биты, которые вызывали ошибку)

Надеюсь, это поможет:)

...