所以我在使用React,Firebase和Node创建的这个基本任务应用程序时遇到了一个小问题。 我有在heroku上托管的工作版本(将在下面发布链接),以便您可以使用它来查看我的意思。
我的问题
如果您访问我的应用程序的链接,您可以看到,当您最初单击“获取任务”按钮时,任务不会加载到屏幕上。 只需两次单击即可将列表填充到屏幕上。
此外,当您单击关闭图标以尝试删除特定任务时,嗯......您将看到自己的双眼会发生什么,哈哈。
我的想法虽然我很高兴它至少有效,但我觉得好像罪魁祸首就是我在grabTasks函数中创建的代码。 不要问我为什么用变量名x创建一个随机的空数组,我也没有线索,这是我能让它工作的唯一方法。 我已经阅读了所有的firebase文档,所以我希望有人可以告诉我这个问题是什么,并且可能建议一个更好的方法来解决这个问题。 代码和链接如下。
链接到工作Heroku应用程序
App.js
// App.js export default class App extends Component { constructor(props) { super(props); this.state = { tasks: [] }; this.grabTasks = this.grabTasks.bind(this); this.handleDelete = this.handleDelete.bind(this); } // Grabs the list of tasks from the firebase database // and then sets the state to x. grabTasks() { var x = []; db.ref('tasks').on('value', function(snapshot) { return x = snapshot.val(); }); this.setState({ tasks : x }); } // In charge of removing the task items when they are clicked. // This function is passed to TaskItems via props handleDelete(taskToDelete) { var newTasks = _.reject(this.state.tasks, function(task) { return task == taskToDelete }); this.setState({tasks: newTasks}); } render() { return ( <div id="wrapper"> <div id="navigation"> <Navbar /> </div> <div id="content"> <div className="container"> <div className="row"> <h2>Tasks</h2> <div onClick={this.grabTasks} className="btn">Get Tasks</div> <TaskItems tasks={this.state.tasks} handleDelete={this.handleDelete} /> </div> </div> </div> </div> ) } }TaskItems.js
// TaskItems Child Component const TaskItems = (props) => { var hello = props.tasks.map((task,index) => { return( <li className="collection-item" key={index}> {task} <a onClick={props.handleDelete.bind(this, task)}> <i className="fa fa-times-circle remove-task" aria-hidden="true"></i> </a> </li> ); }); return ( <div> <ul className="collection"> {hello} </ul> </div> ); } export default TaskItemsSo I am running into a slight issue in regards to this basic task app I am creating with React, Firebase, and Node. I have the working version hosted on heroku(will post link below) so you can use it to see what I mean.
My Issue
If you visit the link to my app, you can see that when you initially click the get tasks button, the tasks do not get loaded to the screen. It takes two clicks to get the list to populate to the screen.
Also, when you click the close icon to try to remove the specific task, well... you will see with your own two eyes what happens, lol.
My Thoughts Although I am happy that it atleast works, I feel as if the main culprit is the code I am creating inside of the grabTasks function. Don't ask why I created a random empty array with the variable name x, I have no clue either, it was the only way I could get it to work. I've read all the firebase docs, so I am hoping someone here can enlighten me on what the issue is, and maybe suggest a better way to go about this. Code & Links below.
Link to working Heroku App
App.js
// App.js export default class App extends Component { constructor(props) { super(props); this.state = { tasks: [] }; this.grabTasks = this.grabTasks.bind(this); this.handleDelete = this.handleDelete.bind(this); } // Grabs the list of tasks from the firebase database // and then sets the state to x. grabTasks() { var x = []; db.ref('tasks').on('value', function(snapshot) { return x = snapshot.val(); }); this.setState({ tasks : x }); } // In charge of removing the task items when they are clicked. // This function is passed to TaskItems via props handleDelete(taskToDelete) { var newTasks = _.reject(this.state.tasks, function(task) { return task == taskToDelete }); this.setState({tasks: newTasks}); } render() { return ( <div id="wrapper"> <div id="navigation"> <Navbar /> </div> <div id="content"> <div className="container"> <div className="row"> <h2>Tasks</h2> <div onClick={this.grabTasks} className="btn">Get Tasks</div> <TaskItems tasks={this.state.tasks} handleDelete={this.handleDelete} /> </div> </div> </div> </div> ) } }TaskItems.js
// TaskItems Child Component const TaskItems = (props) => { var hello = props.tasks.map((task,index) => { return( <li className="collection-item" key={index}> {task} <a onClick={props.handleDelete.bind(this, task)}> <i className="fa fa-times-circle remove-task" aria-hidden="true"></i> </a> </li> ); }); return ( <div> <ul className="collection"> {hello} </ul> </div> ); } export default TaskItems最满意答案
db.ref('tasks')是一种异步方法。 你不应该认为它是同步的。 尝试这个:
grabTasks() { var that = this; db.ref('tasks').on('value', function(snapshot) { var x = snapshop.val(); that.setState({tasks : x}) }); }要在加载屏幕时获取这些任务:
componentDidMount(){ this.grabTasks(); }Your db.ref('tasks') is an async method. You shouldn't think it as sync. Try this:
grabTasks() { var that = this; db.ref('tasks').on('value', function(snapshot) { var x = snapshop.val(); that.setState({tasks : x}) }); }To get those tasks when the screen is loaded :
componentDidMount(){ this.grabTasks(); }
更多推荐
发布评论