我正在关注 Traversey Media 的 React crash course,我想扩展他构建的内容以将 TodoItems 保存到 Firebase 实时数据库。 TodoItems 保存得很好,但不会出现在 UI 中。
我尝试让应用程序以硬编码的 TodoItem 启动,以防出现空数组的问题,但这没有任何帮助。
相关方法:
(完整代码可在 https://github.com/etothepi16/react-todo 获取)
// Delete todo item
delTodo = (id) => {
fire.database().ref(`todos/${id}`).remove()
.then(function(){
this.setState({
// Loop through todos array and filter out item with provided ID
// ... is the spread operator, used here to copy the todos array
todos: [...this.state.todos.filter((todo) => todo.id !== id)]
})
.catch(function(error){
console.log("Remove failed: " + error.message);
})
});
};
// Add todo
addTodo = (title) => {
let id = uuid.v4();
let database = fire.database();
let todosRef = database.ref(`todos/${id}`);
let newTodo = {
id: this.id,
title: title,
completed: false
}
todosRef.set(newTodo).then(
this.setState({todos: [...this.state.todos, newTodo]})
);
};
render() {
return (
<Router>
<div className='App'>
<div className='container'>
<Header />
<Route
exact
path='/'
render={(props) => (
<React.Fragment>
<AddTodo addTodo={this.addTodo} />
<Todos
todos={this.state.todos}
markComplete={this.markComplete}
delTodo={this.delTodo}
/>
</React.Fragment>
)}
/>
<Route path='/about' component={About} />
</div>
</div>
</Router>
);
}
};
class Todos extends Component {
render(){
return this.props.todos.map((todo)=>(
<TodoItem todo={todo} markComplete={this.props.markComplete} delTodo={this.props.delTodo}/>
));
}
}
TodoItem.js
render() {
const { id, title } = this.props.todo;
return (
<div style={this.getStyle()}>
<p>
<input type="checkbox" onChange={this.props.markComplete.bind(this, id)} />{' '}
{ title }
<button className="delete" style={btnStyle} onClick={this.props.delTodo.bind(this,id)}>x</button>
</p>
</div>
)
}
}
如前所述,UI 中没有显示任何 TodoItems。
错误消息:
Warning: Failed prop type: The prop
todos
is marked as required inTodoItem
, but its value isundefined
. in TodoItem (at Todos.js:8) in Todos (at App.js:87) in Route (at App.js:81) in div (at App.js:79) in div (at App.js:78) in Router (created by BrowserRouter) in BrowserRouter (at App.js:77) in App (at src/index.js:4)
当我尝试添加新的 TodoItem 时出现错误: AddTodo error
Error: Reference.set failed: First argument contains undefined in property 'todos.7cda085d-7653-4895-a140-d6f2629af9ca.id'
C:/Users/Paul/Desktop/react-todo/src/App.js:70
67 | title: title, 68 | completed: false 69 | } > 70 | todosRef.set(newTodo).then( ^ 71 | this.setState({todos: [...this.state.todos, newTodo]}) 72 | ); 73 | }; 262 | 263 | this.onSubmit = e => { 264 | e.preventDefault(); > 265 | this.props.addTodo(this.state.title); 266 | this.setState({ 267 | title: '' 268 | });
最佳答案
onClick={this.props.delTodo.bind(this,id)}
您不需要在此处绑定(bind)this
。
您只需创建一个匿名函数,并在该匿名函数中使用给定的 id
调用您的 markComplete
和 delTodo
函数,
render() {
const { id, title } = this.props.todo;
return (
<div style={this.getStyle()}>
<p>
<input type="checkbox" onChange={() => this.props.markComplete(id)} />{' '}
{ title }
<button className="delete" style={btnStyle} onClick={() => this.props.delTodo(id)}>x</button>
</p>
</div>
)
}
}
关于javascript - TodoItems 不会出现在使用 React 和 Firebase 的 UI 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57666575/