对象作为 React 子对象无效(找到:带有键 {username} 的对象)。如果您打算渲染一组子项,请改用数组

Vai*_*tri 1 firebase reactjs google-cloud-firestore

它在 id:doc.id 和 post 中拍摄错误:doc.data()
错误:对象作为 React 子对象无效(找到:带有键 {username} 的对象)。如果您打算渲染一组子项,请改用数组。

const [post, setPost] = useState([]);
      useEffect(() => {
        db.collection("posts").onSnapshot(snapshot => {
          setPost(
            snapshot.docs.map(doc => ({
              id: doc.id,
              post: doc.data(),
            }))
          );
        });
      }, []);
 
      return (
    
          {post.map(({ id, post }) => (
            <Post
              key={id}
              username={post.username}
              caption={post.caption}
              imageURL={post.imageURL}
            />
          ))}
      );
Run Code Online (Sandbox Code Playgroud)

Dan*_*ram 6

当某些 jsx 标记中包含 javascript 对象时,会发生此错误。

就是这么简单。

考虑以下示例:

// A simple javascript object (also a dictionary) containing three keys
const someObject = {
  name: 'Simple Javascript object',
  id: 123,
  someFunction: function() {
    return <p>This function returned more jsx!</p>;
  }
}

const SimpleFunctionComponent = () => <h2>{someObject}</h2>;
Run Code Online (Sandbox Code Playgroud)

需要注意的是,<h2>{someObject}</h2>这里不是html,是jsx。React 将解析它并使用 javascript 在 dom 中创建相应的元素。两个相应的组件标签(like<h2></h2>here)之间/内部的内容被认为是组件的一个或多个子组件。

在这个例子中,如果我尝试渲染<SimpleFunctionComponent />我会得到错误

对象作为 React 子对象无效(找到:带有键 {name, id, someFunction} 的对象)。如果您打算渲染一组子项,请改用数组。

someObject不是有效的 React 子代。据我所知stringint还有更多的 jsx。someObject不是这些东西中的任何一个。

如果我SimpleFunctionComponent稍微修改一下,它将起作用。

const SimpleFunctionComponent = () => (
  <div>
    <h2>STRING: {someObject.name}</h2>
    <p>INT: {someObject.id}</p>
    <p>JSX: {someObject.someFunction()}</p>
  </div>
);
Run Code Online (Sandbox Code Playgroud)

这里唯一能帮助调试此类问题的真正信息是错误消息将为您提供导致错误的对象内部的键。

在 OP 的代码中,错误来自于此

<Post 
    key={id} 
    username={post.username} 
    caption={post.caption} 
    imageURL={post.imageURL} 
/>;
Run Code Online (Sandbox Code Playgroud)

注意:上面的代码是完全有效的,但错误将来自Post组件的渲染,其中任何这些属性用作 React 子项。

例如

// If Post was a functional component
const Post = (props) => {
   return (
       <div>
           <h1>{props.username}</h1>
           <p>{props.caption}</p>
           <img src={props.imageURL} alt="post image"/>
       </div>
   )
}
Run Code Online (Sandbox Code Playgroud)

在不知道post.idor的结构的情况下,post.post我们可以推断出id, post.username, post.caption, 和中的任何一个post.imageURL实际上都是一个包含用户名密钥的对象。

(found: object with keys {username}).

让我们假设它是post.username,OP认为的结构post

const post = {
    id: 'some id',
    post: {
        username: 'some username',
        caption: 'some caption',
        imageURL: 'some image url'
    }
}
Run Code Online (Sandbox Code Playgroud)

当它实际上

const post = {
    id: 'some id',
    post: {
        username: {
            username: 'some username'
        },
        caption: 'some caption',
        imageURL: 'some image url'
    }
}
Run Code Online (Sandbox Code Playgroud)

并且需要username={post.username.username}改为。对于idpost.captionpost.imageURL如果它们实际上是导致错误的对象,这将分别相同。

这是我提供的示例的CodeSandox以及复制 OP 情况的示例。