具有Firebase问题的React阵列映射(React Array Map With Firebase Issue)

编程入门 行业动态 更新时间:2024-10-21 03:55:57
具有Firebase问题的React阵列映射(React Array Map With Firebase Issue)

所以我在使用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 TaskItems 
  
 

So 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(); }

更多推荐

本文发布于:2023-04-28 02:46:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1330299.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:阵列   React   Firebase   Issue   Map

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!