首页 > 解决方案 > getElementByID + .appendhild() [TypeError: 无法在 'Node' 上执行 'appendChild':参数 1 不是 'Node' 类型。]

问题描述

我有一个名为“Article”的自定义组件,我试图通过从数据库中获取它们并将它们呈现为“Article”组件来显示所有文章。

function renderArticle(doc){
    var article = '<Article name="' + doc.data().name + '" content="' + doc.data().content + '" id="' + doc.data().id + '"/>'
    document.getElementById('articles-list').appendChild(article)

}
 
const db = firebase.firestore()
db.collection('articles').get().then((snapshot) => {
    snapshot.docs.forEach(doc => {
      renderArticle(doc)
    })
  })

当我运行它时,控制台返回TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

我被困住了...

标签: javascriptreactjs

解决方案


AS @Calvin Nunes 说您需要将节点传递给 document.createElement(),但是当您标记 reactjs 时,也许您也可以使用一些建议。

在 React 中,我们必须渲染异步传入的数据(例如,您从数据库中获取的文档)的方式是将它们跟踪到组件状态。

在第一时间,我们渲染 null 或一些加载指示器并触发请求以获取我们的数据。加载数据后,我们设置状态,因此我们的组件将重新渲染,我们可以渲染状态中的内容。

如果您使用具有生命周期的组件,您的代码将类似于:

import React, {Component} from 'react';

class ArticleList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      docs: null,
    };
  }

  componentDidMount() {
    db.collection('articles').get().then((snapshot) => {
      this.setState({docs: snapshot.docs});
    })
  }

  render() {
    if (docs === null) return null;
    return (
      <div>
        {docs.map((doc) => {
          return (
            <Article
              content={doc.data().content}
              key={doc.data().id}
              id={doc.data().id}
              name={doc.data().name}
            />
          );
        })}
      </div>
    );
  }
}

export default ArticleList;

如果您使用带有钩子的函数,您的代码将如下所示:

import React, {useEffect, useState} from 'react';
import Article from './Article'; // your other component

function ArticleList () {
  const [docs, setDocs] = useState(null);
  const db = firebase.firestore();
  useEffect(() => {
    db.collection('articles').get().then((snapshot) => {
      setDocs(snapshot.docs);
    })
  }, [db, setDocs]);
  if (docs === null) return null;
  return (
    <div>
      {docs.map((doc) => {
        return (
          <Article
            content={doc.data().content}
            key={doc.data().id}
            id={doc.data().id}
            name={doc.data().name}
          />
        );
      })}
    </div>
  );
}

export default ArticleList;

您可能还需要记住 db 对象,以便只运行一次 useEffect 挂钩,但这不是重点。


推荐阅读