首页 > 解决方案 > TypeError:无法在 ReactJS 中读取 null 的属性“appendChild”

问题描述

我正在 ReactJS 中创建一个 chatApp,但我遇到了这个错误:

TypeError:无法读取 null 的属性“appendChild”

我已经调用了“printmessage”,但它仍然返回 null。(第 144 行) APP.JS:

import React from 'react'
import './App.css';
import firebase from 'firebase'

const firebaseConfig = {
  apiKey: "AIzaSyBTwRj0vzQn4v-IRvRQ7UQSPMnBNT0Gi0A",
  authDomain: "whatapp-02.firebaseapp.com",
  databaseURL: "https://whatapp-02-default-rtdb.firebaseio.com",
  projectId: "whatapp-02",
  storageBucket: "whatapp-02.appspot.com",
  messagingSenderId: "1085780260212",
  appId: "1:1085780260212:web:540d871a14bb7536b4e821"
};

firebase.initializeApp(firebaseConfig)

class App extends React.Component {
  
  constructor(props){
    super(props);
    this.state = {
      name: ' ',
      partner: ' ',
      key: ' ',
      allkey: ' ',
      message: ' ',
      prevmessage: ' ',
      username: ' ',
      partnermessage: ' ',
      chatpartner: ' ',
    };
  }

  login=()=>{
    var key = Math.random().toString().substring(2, 8);
    this.setState({key: key,});
    firebase.database().ref('USER-'+key).set({
      key: key,
      partner: ' ',
    });
    document.getElementsByClassName("logindiv")[0].style.display = "none";
    document.getElementsByClassName("chatdiv")[0].style.display = "block";
    setInterval(this.update_partner, 1000)
  }

  get_user=()=>{
    var parsedallkey = parseInt(this.state.key,10) + parseInt(this.state.partner,10);
    var input = prompt("enter user code:")
    firebase.database().ref('USER-'+this.state.key).set({
     partner: input,
    });
    firebase.database().ref('USER-'+input).set({
      partner: this.state.key,
    });
    this.setState({allkey: parsedallkey})
  }
   
  update_partner=()=>{
  var parsedallkey = parseInt(this.state.key,10) + parseInt(this.state.partner,10);
  firebase.database().ref('USER-'+this.state.key).once('value', (snapshot)=>{
    var partner = snapshot.val().partner
    this.setState({partner: partner})
  })
  this.setState({allkey: parsedallkey})
  setInterval(this.identify_message, 2000) 
  }

  handle_message=(e)=>{
   this.setState({message: e.target.value});
   console.log(this.state.message)
  }

  send_message=()=>{
    firebase.database().ref('MESSAGE'+this.state.allkey).push().set({ //Save user name and message in reference "messages" in firebase database
        sender: this.state.key,
        message: this.state.message
    });
  }

  render(){
    return (<>
     <div className='logindiv'>
     <h1 style={{float: 'left'}}>chatApp</h1>
       <a href="#" role="button" onClick={this.login} style={{position:'relative',top:29,float: 'right'}}>Guest login</a>
     <div style={{position: 'relative', top:90,height:440, textAlign: 'center', backgroundImage: "url(https://cdn.wallpapersafari.com/20/74/x58BEZ.jpg)"}}>
       <h2 style={{position: 'relative',top:50,color: 'white'}}>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec dapibus sapien, quis sagittis quam. Pellentesque lacus mi, bibendum ac augue non, placerat tempus justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Morbi laoreet tellus consequat pulvinar pulvinar. Cras neque ante, varius vel feugiat nec, cursus nec sapien. Sed <br></br>viverra ullamcorper accumsan. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc vitae pellentesque lectus. Vivamus eget urna at tellus porta sodales at quis urna. <br></br>Aliquam non enim non ipsum viverra gravida a convallis metus. Aenean dapibus accumsan nunc, non vestibulum nulla semper ut. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur commodo posuere ligula id varius. Morbi rutrum eu arcu sit amet viverra. Vestibulum hendrerit sodales eros eget imperdiet.</h2>
     </div>
     </div>

     <div className='chatdiv'>
<div>
  {/* Navbar */}
  <nav className="navbar navbar-expand-lg navbar-light bg-light">
    {/* Container wrapper */}
    <div className="container-fluid">
      {/* Navbar brand */}
      <h4 className="navbar-brand" >Your key: {this.state.key}</h4>
      {/* Toggle button */}
      {/* Collapsible wrapper */}
      <div className id>
        {/* Search form */}
        <form className="d-flex input-group w-auto ml-auto">
          <input type="search" className="form-control align-self-center" placeholder=" Enter a user code..." aria-label="Search" />
          <button className="btn btn-outline-primary" type="button" data-mdb-ripple-color="dark" onClick={this.get_user}>
            Search
          </button>
        </form>
      </div>
      {/* Collapsible wrapper */}
    </div>
    {/* Container wrapper */}
  </nav>
  {/* Navbar */}
  <div className="copntainer-fluid">
    <div className>
      <div className="form-group">
        <label htmlFor="exampleFormControlTextarea3" />
        <ul id="printmessage"></ul>
      </div>
    </div>
    <form className="d-flex input-group w-auto ml-auto">
      <input type="search" className="form-control align-self-center" placeholder=" Enter your message..." aria-label="Search" />
      <button className="btn btn-outline-primary" type="button" onClick={this.send_message} data-mdb-ripple-color="dark">
        Send
      </button>
    </form>
  </div>
</div>


     </div>
  </>);
  }

  identify_message=()=>{
    firebase.database().ref('MESSAGE'+this.state.allkey).limitToLast(1).on("child_added", (snapshot)=>{
      if(snapshot.val().sender + ": " + snapshot.val().message + ' , you said' === this.state.prevmessage || this.state.partnermessage === snapshot.val().sender + ": " + snapshot.val().message + ' , he said'){}else{
      if(snapshot.val().sender === this.state.key){
        var li = document.createElement("li")
        li.innerHTML = snapshot.val().sender + ": " + snapshot.val().message + ' , you said'; 
        console.log(snapshot.val().sender + ": " + snapshot.val().message + ' , you said')
        console.log(this.state.allkey)
        this.setState({prevmessage: snapshot.val().sender + ": " + snapshot.val().message + ' , you said'})
        document.getElementById("printmessages").appendChild(li)
      }else if(snapshot.val().sender === this.state.partner){
          var li = document.createElement("li")
          li.innerHTML = snapshot.val().sender + ": " + snapshot.val().message + ' , he said';
          document.getElementById("printmessages").appendChild(li)
          console.log(snapshot.val().sender + ": " + snapshot.val().message + ' , he said')
          this.setState({partnermessage: snapshot.val().sender + ": " + snapshot.val().message + ' , he said'})
      }
    }
   });
  }


}

export default App;

我正在使用 React-CLI。我还在 public/index.html 中使用 CDN 集成了引导程序。

标签: javascriptreactjs

解决方案


您的 DOM 搜索存在问题。您正在寻找 idprintmessages不存在的元素,而不是寻找 id 为的列表元素printmessage。您只需要更改document.getElementById以查找正确的元素,如下所示:

document.getElementById("printmessage").appendChild(li)

此外,正如评论中所说,这与 React 无关,因为您是渲染内容的人。您应该设法找到一种方法来使用方法“附加”组件内的内容。


推荐阅读