簡體   English   中英

React.js 使用相同的輸入文本框編輯 Todo 項

[英]React.js Edit Todo item using same input text box

我已經實現了簡單的一頁 Todo 應用程序,具有添加、編輯和刪除功能。 大部分部分已經完成,但我有一點被卡住了。 當我單擊編輯按鈕時,我想用單擊行的值填充頂部的輸入文本框,然后在編輯后我想在列表視圖中更新。 你能不能指導我一下。

我創建了一個小提琴來解釋它。

這是我的存儲庫: https : //github.com/JigneshRaval/react-todo-app

JSFiddle 網址: https://jsfiddle.net/jigneshraval/3b3dabr6/20/ ://jsfiddle.net/jigneshraval/3b3dabr6/20/

還粘貼了下面的工作代碼,可以通過單擊“運行代碼片段”按鈕來運行這些代碼。

 const Title = ({ todoCount }) => { return ( <div> <div> <h1>Todos: ({todoCount})</h1> </div> </div> ); } var randomString = function (length) { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; } class TodoForm extends React.Component { // Input Tracker constructor(props) { super(props); console.log(props.editTodo.title); this.state = { value: props.editTodo.title }; this.input; this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ value: event.target.value }) } handleSubmit(event) { event.preventDefault(); console.log(event.target); let newTodoTitle = event.target.querySelector('input'); this.props.addTodo(this.input.value); newTodoTitle.value = ''; } renderAddTodoForm() { // Return JSX return ( <form onSubmit={this.handleSubmit}> {/*<form onSubmit={(e) => { e.preventDefault(); this.props.addTodo(this.input.value); this.input.value = ''; }}>*/} <input className="form-control col-md-12 add-form" ref={(input) => this.input = input} value={this.state.value} onChange={this.handleChange.bind(this)} /> <br /> </form> ); } render() { return this.renderAddTodoForm(); } } // 3. Single Todo // ================================ const Todo = ({ todo, remove, edit }) => { // Each Todo return ( <li className="list-group-item"> <a href="#" data-todoid={todo._id} name="todoTitle" data-toggle="tooltip" data-placement="top" title="Click on item to delete.">{todo.title} = {todo.status}</a> <button className="btn btn-danger float-right" onClick={() => { remove(todo._id) }}>Delete</button> <button className="btn btn-primary float-right" onClick={() => { edit(todo._id) }}>Edit</button> </li>); } // 2. Todo List // ================================ const TodoList = ({ todos, remove, edit }) => { // Map through the todos const todoNode = todos.map((todo) => { return (<Todo todo={todo} key={todo._id} remove={remove} edit={edit} />) }); return (<ul className="list-group" style={{ marginTop: '30px' }}>{todoNode}</ul>); } // 1. Main TODO App // ================================ class TodoApp extends React.Component { constructor(props) { super(props); this.state = { data: [ { "title": "Buy Milk", "status": "pending", "_id": "3QACIouhZZlhmm6T" }, { "title": "Buy new computer book", "status": "pending", "_id": "9Xz2MSHIeh87WMgF" }, { "title": "Fetch Money", "status": "pending", "_id": "DZvP2o5Dd4t9J3Ax" }, { "title": "Play new game", "status": "pending", "_id": "Dp3J6BacTeG8ijV8" }, { "title": "new 2", "status": "pending", "_id": "ECDUmbjOt4vtOKSv" }, { "title": "sdfsdafsaf", "status": "pending", "_id": "GwHBilbjsbXipQuI" }, { "title": "New 10", "status": "pending", "_id": "HGWGsNEVFNXIGZ8S" }, { "title": "ppp", "status": "pending", "_id": "IExYBTFUFkGoHqyN" } ], isEditing: false, editTodo: {} } } // Add Todo addTodo(value) { this.state.data.push({ "title": value, "status": "pending", "today": { "$$date": Date.now() }, "_id": randomString(16) }); this.setState({ data: this.state.data }); } // Edit Todo editTodo(todoId) { const remainder = this.state.data.filter((todo) => { if (todo._id === todoId) return todo; }); this.setState({ isEditing: true, editTodo: remainder[0] }); } // Remove Todo removeTodo(id) { // Filter all todos except the one to be removed const remainder = this.state.data.filter((todo) => { if (todo._id !== id) return todo; }); this.setState({ data: remainder }); } handleInputChange(newValue) { console.log(newValue); } render() { return ( <main> <div className="container"> <Title todoCount={this.state.data.length} /> <TodoForm isEditing={this.state.isEditing} handleInputChange={this.handleInputChange.bind()} editTodo={this.state.editTodo} addTodo={this.addTodo.bind(this)} /> <TodoList todos={this.state.data} remove={this.removeTodo.bind(this)} edit={this.editTodo.bind(this)} /> </div> </main> ) } } ReactDOM.render( <TodoApp />, document.getElementById('app') );
 <script src="https://unpkg.com/react@16.2.0/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16.2.0/umd/react-dom.development.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" /> <div id="app"></div>

任何人都可以請指導我。

您需要向您的 ToDoForm 組件添加如下的生命周期鈎子,如下所示。 但是在 setState 中添加條件,以便僅在 next 與 this.state.value 不同時才調用它

componentWillReceiveProps (next) {
   this.setState({value: next.editTodo.title});
}

這將填充表單中的文本。 您可以在此行之后進行進一步更改。

請參閱我們應該使用 componentWillReceiveProps 而不是 componentWillUpdate 來設置狀態

我會將所有內容拆分為 2 個組件:TodoApp 和 Todo。


TodoApp 有一個表單和一個包含所有子信息的數組。

Todo 有它的功能和它的信息要顯示。


然后使用像這個答案中的正常模式: How to update parent's state in React? .

我希望這有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM