Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在firebase子对象更新事件上未重新渲染的React组件_Javascript_Reactjs_Firebase_Firebase Realtime Database - Fatal编程技术网

Javascript 在firebase子对象更新事件上未重新渲染的React组件

Javascript 在firebase子对象更新事件上未重新渲染的React组件,javascript,reactjs,firebase,firebase-realtime-database,Javascript,Reactjs,Firebase,Firebase Realtime Database,我编写了一个基本的React+Firebase应用程序来确定它是如何工作的 我有一个react组件(ViewPosts),它根据Firebase数据库返回的数据集返回react组件列表(Post) 我已在componentDidMount() 我附加的所有事件都正常工作,但只有更改的子事件没有重新呈现页面。但是我添加了一个console.log,只是为了检查事件是否被触发,它是否被激活。(我正在使用firebase控制台更新/删除值) 我认为这可能是键的问题,所以我甚至添加了一个索引使其唯一,但

我编写了一个基本的React+Firebase应用程序来确定它是如何工作的

我有一个react组件(ViewPosts),它根据Firebase数据库返回的数据集返回react组件列表(Post

我已在
componentDidMount()

我附加的所有事件都正常工作,但只有更改的子事件没有重新呈现页面。但是我添加了一个
console.log
,只是为了检查事件是否被触发,它是否被激活。(我正在使用firebase控制台更新/删除值)

我认为这可能是键的问题,所以我甚至添加了一个索引使其唯一,但仍然没有运气。我在这里遗漏了什么吗?为什么代码会给我这种行为

由于React仅更新更新的组件,因此即使我删除或向列表中添加了新组件,列表也不会更新,但如果我删除了一个组件,并且该组件恰好位于更新组件(Post)上方,则由于React被迫重新呈现该组件下方的列表,我可以看到更新的值

请帮助我确定发生这种情况的原因

查看帖子

import React, { Component } from 'react';
import * as firebase from 'firebase';
import Post from './Post';

var listItems = null;
var starCountRef = null;
class ViewPosts extends Component {

  constructor(props) {
   super(props);
   this.state = {renderedList: []};
   this.getDatafromDB = this.getDatafromDB.bind(this);
   starCountRef = firebase.database().ref('posts');
  }

  getDatafromDB() {
    listItems = [];
    starCountRef.once('value', snapshot => {
      var results = snapshot.val();
      var resultsKeys = Object.keys(results);
      listItems = resultsKeys.map((key,i) => <Post key={key.toString() + i} value={results[key].value + i } />);

      this.setState({
        renderedList : listItems
      });
    });
  }
  componentDidMount(){

    // Get the data on a post that has been removed
    starCountRef.on("child_removed", snapshot =>  {
      var deletedPost = snapshot.val();
      console.log("The post valued '" + deletedPost.value + "' has been deleted");
      this.getDatafromDB();
    });

    // Get the data on a post that has been removed
    starCountRef.on("child_added", snapshot =>  {
      var addedPost = snapshot.val();
      console.log("The post value '" + addedPost.value + "' has been added");
      this.getDatafromDB();
    });

    starCountRef.on("child_changed", snapshot =>  {
      var changedPost = snapshot.val();
      console.log("The updated post value is " + changedPost.value);
      this.getDatafromDB();
      console.log("this.state.listItems " + this.state.renderedList);
    });

  }
   render() {
   return(
     <div>
      <ul>
        {this.state.renderedList}
      </ul>
      </div>
   );
 }
}

export default ViewPosts;
import React, { Component } from 'react';

class Post extends Component {

  constructor(props) {
   super(props);
   this.state = {value: props.value};
  }

 render() {
   return(
     <li>{this.state.value}</li>
   );
 }
}

export default Post;
import React,{Component}来自'React';
从“firebase”导入*作为firebase;
从“./Post”导入Post;
var listItems=null;
var starCountRef=null;
类ViewPosts扩展组件{
建造师(道具){
超级(道具);
this.state={renderedList:[]};
this.getDatafromDB=this.getDatafromDB.bind(this);
starCountRef=firebase.database().ref('posts');
}
getDatafromDB(){
listItems=[];
starCountRef.once('value',快照=>{
var results=snapshot.val();
var resultskies=Object.keys(结果);
listItems=resultsKeys.map((键,i)=>);
这是我的国家({
renderedList:listItems
});
});
}
componentDidMount(){
//获取已删除帖子的数据
starCountRef.on(“已删除子项”,快照=>{
var deletedPost=snapshot.val();
log(“post-value'+deletedPost.value+“'已被删除”);
这是.getDatafromDB();
});
//获取已删除帖子的数据
starCountRef.on(“添加的子项”,快照=>{
var addedPost=snapshot.val();
console.log(“已添加post值'+addedPost.value+”);
这是.getDatafromDB();
});
starCountRef.on(“子项更改”,快照=>{
var changedPost=snapshot.val();
log(“更新后的post值为”+changedPost.value);
这是.getDatafromDB();
log(“this.state.listItems”+this.state.renderdList);
});
}
render(){
返回(
    {this.state.renderList}
); } } 导出默认的viewpost;
发布

import React, { Component } from 'react';
import * as firebase from 'firebase';
import Post from './Post';

var listItems = null;
var starCountRef = null;
class ViewPosts extends Component {

  constructor(props) {
   super(props);
   this.state = {renderedList: []};
   this.getDatafromDB = this.getDatafromDB.bind(this);
   starCountRef = firebase.database().ref('posts');
  }

  getDatafromDB() {
    listItems = [];
    starCountRef.once('value', snapshot => {
      var results = snapshot.val();
      var resultsKeys = Object.keys(results);
      listItems = resultsKeys.map((key,i) => <Post key={key.toString() + i} value={results[key].value + i } />);

      this.setState({
        renderedList : listItems
      });
    });
  }
  componentDidMount(){

    // Get the data on a post that has been removed
    starCountRef.on("child_removed", snapshot =>  {
      var deletedPost = snapshot.val();
      console.log("The post valued '" + deletedPost.value + "' has been deleted");
      this.getDatafromDB();
    });

    // Get the data on a post that has been removed
    starCountRef.on("child_added", snapshot =>  {
      var addedPost = snapshot.val();
      console.log("The post value '" + addedPost.value + "' has been added");
      this.getDatafromDB();
    });

    starCountRef.on("child_changed", snapshot =>  {
      var changedPost = snapshot.val();
      console.log("The updated post value is " + changedPost.value);
      this.getDatafromDB();
      console.log("this.state.listItems " + this.state.renderedList);
    });

  }
   render() {
   return(
     <div>
      <ul>
        {this.state.renderedList}
      </ul>
      </div>
   );
 }
}

export default ViewPosts;
import React, { Component } from 'react';

class Post extends Component {

  constructor(props) {
   super(props);
   this.state = {value: props.value};
  }

 render() {
   return(
     <li>{this.state.value}</li>
   );
 }
}

export default Post;
import React,{Component}来自'React';
类Post扩展组件{
建造师(道具){
超级(道具);
this.state={value:props.value};
}
render(){
返回(
  • {this.state.value}
  • ); } } 导出默认帖子;
    我引入了一个新属性“uid”,并将该uid映射到组件的键。 然后,当我更新UID和值时,React将其作为一个更新,并重新呈现该组件

    即使在移除键上方的一个组件之前,我已经包含了键的索引,该键也将是相同的,这解释了为什么当我从顶部移除一个组件时它会被渲染

    基本上,如果有多个相同类型的组件,则必须使用唯一键绑定这些组件,并且除非该键更改,否则即使值更改,React也不会重新呈现该组件

    据我所知,React所做的是在后台创建一个虚拟DOM,并将其与现有DOM进行比较,然后只重新渲染更改的组件。这样做的时候,如果有多个键,它会查找键,如果相同,它会跳过整个组件

    另外,如果您想知道我是如何创建一个密钥的,我会使用lodash的
    ..uniqueId([prefix='')
    方法生成一个密钥


    谢谢,

    克隆您的对象,然后设置状态

    const clonelistItems = listItems.slice();
    this.setState({
        renderedList :clonelistItems
    });