2017-06-21 6 views
1

Ich habe den Anfang einer Todo-Liste in reactjs geschrieben und wollte die Funktionalität der Todos zum Zustand verbessern. Momentan werde ich den Wert in ein Array setzen, das sich in dem Zustand befindet, und dann das ausgewählte li-Element abspleißen. Es scheint ein wenig buggy zu sein, wenn Sie die erste todo hinzufügen. Sollte ich mit Hilfe von Unveränderlichkeitshilfen das erreichen? Es scheint Overkill, um eine andere Sache hinzuzufügen, die in normalen js erreicht werden kann.ReactJs Todo Liste push state

//Input component 
const Input = props => { 
    return (
    <div className="form-group"> 
     <input 
     className="form-control" 
     value={props.value} 
     onChange={props.update} 
     type="text" 
     /> 
     <button className="btn btn-default" onClick={props.handleClick}> 
     Add Todo 
     </button> 
    </div> 
); 
}; 
//display list of todos 
const Displaytodo = (props) => { 
    const todolist = props.todo; 
    const listItems = todolist.map((todo, index) => 
    <li 
     className={ 
     props.highlight ? 'list-unstyled todoItem highlight' : 'list-unstyled todoItem ' 
     } 
     key={index}> 
     {todo} 
     <div 
     onClick={props.removeTodo.bind(this, index)} 
     className="removeTodo"> 
     <i className="fa fa-trash" /> 
     </div> 
     <div onClick={props.changeHighlight.bind(this,index)} className="checkTodo"> 
     <i className="fa fa-check-circle" onClick={props.highlight} /> 
     </div> 
    </li> 
); 

    return <ul className="todos">{listItems}</ul>; 
}; 
//controlled state component 
class Layout extends React.Component { 
    constructor() { 
    super(); 
    this.state = { text: "Hello", todo: [], highlight: false }; 
    } 
    update(e) { 
    this.setState({ text: e.target.value }); 
    } 
    handleClick() { 
    const text = this.state.text; 
    if (text.length > 0) { 
     this.setState(
     { todo: this.state.todo.concat(text), text: "", highlight: false }, 
     function() { 
      console.log(this.state.todo); 
     } 
    ); 
    } else { 
     alert("please enter something"); 
    } 
    } 
    removeTodo(e) { 
    this.state.todo.splice(e, 1); 
    this.setState({ todo: this.state.todo }); 
    } 

    changeHighlight(index, e) { 
    const highlight = this.state.highlight; 

    this.setState(prevState => ({ 
     highlight: !prevState.highlight 
    })); 
    } 

    render() { 
    return (
     <div className="container"> 
     <div className="row"> 

      <div className="col-md-4 col-md-offset-4"> 
      <div className="wrapper"> 
       <h1>Todo List</h1> 

       <Input 
       value={this.state.text} 
       update={this.update.bind(this)} 
       handleClick={this.handleClick.bind(this)} 
       /> 
       <Displaytodo 
       removeTodo={this.removeTodo.bind(this)} 
       todo={this.state.todo} 
       changeHighlight={this.changeHighlight.bind(this)} 
       highlight={this.state.highlight} 
       /> 
      </div> 

      </div> 
     </div> 
     </div> 
    ); 
    } 
} 

const app = document.getElementById("app"); 

ReactDOM.render(<Layout />, app); 

https://codepen.io/mhal12/pen/MomWVg

Auch wenn der Benutzer auf das grüne Häkchen klickt, wird die Reihe von Makeln Klasse ‚Highlight‘ ab und zu, aber in der Konsole markieren Sie es einen Fehler gibt. die Links zu

https://facebook.github.io/react/docs/error-decoder.html?invariant=94&args[]=onClick&args[]=boolean

Antwort

1

einfach die onClick auf <i className="fa fa-check-circle" onClick={props.highlight} /> entfernen.

Wie für die Hervorhebung auf jedem todo, ist es ein bisschen komplexer. Sie müssen eine id auf jeder todo haben, und dann die id an die changeHighlight Funktion übergeben. Sie müssen die Hervorhebung aus dem globalen Status entfernen und einen highlight booleschen Wert auf jedem todo zuweisen. Dann müssen Sie todos entsprechend anzeigen.

Gleiches für die removeTodo-Funktion übergeben Sie in id, um es in der übergeordneten Komponente zu entfernen.

Hier ist der vollständige Code:

const Input = props => { 
    return (
    <div className="form-group"> 
     <input 
     className="form-control" 
     value={props.value} 
     onChange={props.update} 
     type="text" 
     /> 
     <button className="btn btn-default" onClick={props.handleClick}> 
     Add Todo 
     </button> 
    </div> 
); 
}; 
const Displaytodo = (props) => { 
    const changeHighlight = function(id) { 
    props.changeHighlight(id); 
    } 

    const removeTodo = function(id) { 
    props.removeTodo(id); 
    } 

    const todolist = props.todo; 
    const listItems = todolist.map((todo, index) => 
    <li 
     className={ 
     todo.highlight ? 'list-unstyled todoItem highlight' : 'list-unstyled todoItem ' 
     } 
     key={todo.id}> 
     {todo.text} 
     <div 
     onClick={removeTodo.bind(event, todo.id)} 
     className="removeTodo"> 
     <i className="fa fa-trash" /> 
     </div> 
     <div onClick={changeHighlight.bind(event, todo.id)} className="checkTodo"> 
     <i className="fa fa-check-circle" /> 
     </div> 
    </li> 
); 

    return <ul className="todos">{listItems}</ul>; 
}; 
class Layout extends React.Component { 
    constructor() { 
    super(); 
    this.state = {text: "Hello", todo: []}; 
    } 
    update(e) { 
    this.setState({ text: e.target.value }); 
    } 
    handleClick() { 
    const text = this.state.text; 
    if (text.length > 0) { 
     this.setState(
     { todo: this.state.todo.concat({ 
      id: this.state.todo.length + 1, 
      text: this.state.text, 
      highlight: false 
     }), text: ""}, 
     function() { 
      console.log(this.state.todo); 
     } 
    ); 
    } else { 
     alert("Please enter something"); 
    } 
    } 
    removeTodo(id) { 
    let todos = this.state.todo; 

    for (let i = 0; i < todos.length; i++) { 
     let todo = todos[i]; 
     if (todo.id == id) { 
     todos.splice(i, 1); 
     } 
    } 

    this.setState({ todo: todos }); 
    } 

    changeHighlight(id) {  
    let todos = this.state.todo; 

    for (let i = 0; i < todos.length; i++) { 
     let todo = todos[i]; 
     if (todo.id == id) { 
     todos[i].highlight = !todos[i].highlight; 
     } 
    } 

    this.setState({ 
     todo : todos 
    }); 
    } 

    render() { 
    return (
     <div className="container"> 
     <div className="row"> 

      <div className="col-md-4 col-md-offset-4"> 
      <div className="wrapper"> 
       <h1>Todo List</h1> 

       <Input 
       value={this.state.text} 
       update={this.update.bind(this)} 
       handleClick={this.handleClick.bind(this)} 
       /> 
       <Displaytodo 
       removeTodo={this.removeTodo.bind(this)} 
       todo={this.state.todo} 
       changeHighlight={this.changeHighlight.bind(this)} 
       /> 
      </div> 

      </div> 
     </div> 
     </div> 
    ); 
    } 
} 

const app = document.getElementById("app"); 

ReactDOM.render(<Layout />, app); 
+0

Dank Steve, völlig verfehlt, dass Onclick, wo ich hatte sie orginally! Moving Highlight aus dem globalen Zustand funktioniert perfekt, danke. – Michaelh

+0

Kein Problem. Bitte markieren Sie die Antwort als Lösung, wenn es Ihr Problem gelöst hat :) –

+0

Ich habe Ihre vorgeschlagenen Änderungen an meinem Code angewendet, ich habe auch bemerkt, dass meine Spleißfunktion tatsächlich das erste Element im Array anstelle des ausgewählten Elements entfernt. Überprüfen Sie meinen CodePen zum Beispiel, jede Hilfe sehr geschätzt .. PS. noch nicht rep to upvote :( – Michaelh

Verwandte Themen