对象作为React子代无效。如果要渲染子级集合,请改用数组

时间:2018-09-20 15:49:46

标签: javascript arrays reactjs

我正在用Rails后端设置一个React应用。我收到错误消息“对象作为React子对象无效(找到:带有键{id,name,info,created_at,updated_at}的对象)。如果要渲染子代的集合,请改用数组。” < / p>

这是我的数据:

[
    {
        "id": 1,
        "name": "Home Page",
        "info": "This little bit of info is being loaded from a Rails 
        API.",
        "created_at": "2018-09-18T16:39:22.184Z",
        "updated_at": "2018-09-18T16:39:22.184Z"
    }
]

我的代码如下:

import React from 'react';

class Home extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      homes: []
    };
  }

  componentDidMount() {
    fetch('http://localhost:3000/api/homes')
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            homes: result
          });
        },
        // error handler
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {

    const { error, isLoaded, homes } = this.state;

    if (error) {
      return (
        <div className="col">
          Error: {error.message}
        </div>
      );
    } else if (!isLoaded) {
      return (
        <div className="col">
          Loading...
        </div>
      );
    } else {
      return (
        <div className="col">
          <h1>Mi Casa</h1>
          <p>This is my house y'all!</p>
          <p>Stuff: {homes}</p>
        </div>
      );
    }
  }
}

export default Home;

我在做什么错了?

21 个答案:

答案 0 :(得分:13)

您的数据homes是一个数组,因此您必须使用Array.prototype.map()遍历该数组才能工作。

return (
    <div className="col">
      <h1>Mi Casa</h1>
      <p>This is my house y&apos;all!</p>
      {homes.map(home => <div>{home.name}</div>)}
    </div>
  );

答案 1 :(得分:5)

我希望它会帮助别人。

当您无意中将对象发送到React子组件时,似乎也会发生此错误。

它的示例将如下所示传递给子组件新的Date('....'):

 const data = {name: 'ABC', startDate: new Date('2011-11-11')}
 ...
 <GenInfo params={data}/>

如果将其作为子组件参数的值发送,则将发送复杂的对象,并且可能会收到与上述相同的错误。

检查是否传递类似的东西(在引擎盖下生成对象)。

答案 2 :(得分:3)

尽管并非特定于答案,但是当您使用{}

在JavaScript上下文中错误地使用JavaScript表达式时,通常会发生此错误

例如

let x=5;

export default function App(){ return( {x} ); };

正确的方法是

let x=5;
export default function App(){ return( x ); };

答案 3 :(得分:2)

有同样的问题,就我而言, 1.将字符串解析为Json 2.确保在渲染视图时,不要尝试显示整个对象,而是显示object.value

data = [
{
    "id": 1,
    "name": "Home Page",
    "info": "This little bit of info is being loaded from a Rails 
    API.",
    "created_at": "2018-09-18T16:39:22.184Z",
    "updated_at": "2018-09-18T16:39:22.184Z"
}];
var jsonData = JSON.parse(data)

那我的看法

return (
<View style={styles.container}>
  <FlatList
    data={jsonData}
    renderItem={({ item }) => <Item title={item.name} />}
    keyExtractor={item => item.id}
  />
</View>);

因为我使用的是数组,所以我使用平面列表进行显示,并确保我使用的是object.value,而不是object,否则会遇到同样的问题

答案 4 :(得分:2)

我在创建自定义模式时遇到了类似的错误。

const CustomModal = (visible, modalText, modalHeader) => {}

问题是我没有将值包装在大括号中。

const CustomModal = ({visible, modalText, modalHeader}) => {}

如果有多个值要传递给组件,则应在其周围使用大括号。

答案 5 :(得分:2)

Objects are not valid as a React child

我也遇到了同样的错误,但情况不同。我正在学习 react useReducer hook 并实现了一个带有递增、递减和重置按钮的计数器,我试图在屏幕上显示计数,但我遇到了上述错误。

在代码中,我将 useReducer 钩子返回的计数声明为对象,我直接尝试返回它而不是它的 count 属性

我实际上应该返回 count.count 并且我只返回 count(对象本身)而不是属性。

我们可以对对象进行字符串化并返回字符串。

import React, { useReducer } from "react";

const initialState = {
count:0,
}
const reducer = (state, action) => {
    switch (action.type) {
        case 'increment':
            return {count:state.count + 1}
        case 'decrement':
            return {count:state.count - 1}
        case 'reset':
            return initialState
        default:
            return state
    }
}

function CounterWithReducer(props) {
  const [count, dispatch] = useReducer(reducer, initialState);

  return (
    <>
      <h1>{count}</h1>
      <button onClick={()=>{dispatch({type:'increment'})}}>Increment</button>

      <button onClick={()=>{dispatch({type:"decrement"})}}>Decrement</button>
      <button onClick={()=>{dispatch({type:"reset"})}}>Reset</button>
    </>
  );
}

export default CounterWithReducer;

在上面的代码中

{count}

这部分(在返回部分)是我犯错的地方,而不是 count 我需要使用 count.count

总而言之,如果您尝试在屏幕上显示对象,则不能使用 JSON.stringify() 或尝试显示对象的任何属性。

我正处于开发者生活的早期阶段,如有任何拼写错误,请原谅我。

答案 6 :(得分:1)

在我的情况下,我要渲染的数据包含一个对象,该对象位于数组的对象内部,因此,这给了错误,因此对于在那里的其他人,也请检查一次您的数据,如果它包含一个对象,您需要将其转换为数组以打印其所有值,或者如果需要特定值,则使用。

我的数据:

body:“ d fvsdv”

照片:“ http://res.cloudinary.com/imvr7/image/upload/v1591563988/hhanfhiyalwnv231oweg.png

发布者:{_id:“ 5edbf948cdfafc4e38e74081”,名称:“ vit”} //这是我正在谈论的对象。

title:“ c sx”

__ v:0

_id:“ 5edd56d7e64a9e58acfd499f”

原始:对象

仅打印单个值

<h5>{item.postedby.name}</h5>

答案 7 :(得分:1)

我也出现了这个错误,我把花括号去掉了,希望能帮到别人。

你可以看到,我没有把 con 放在花括号里,错误发生了,当我去掉大括号时,错误消失了。

const modal = (props) => {
const { show, onClose } = props;

let con = <div className="modal" onClick={onClose}>
        {props.children}
        </div>;

return show === true ? (
    {con}
) : (
    <div>hello</div>
);

有一篇关于大括号用法的文章。click here

答案 8 :(得分:0)

在您的状态下,home初始化为数组 homes: []

作为回报,您尝试渲染主屏幕(数组)。 <p>Stuff: {homes}</p>

无法以这种方式完成---如果要渲染它,则需要在每个单个项目中渲染一个数组。例如:使用map()

例如:{home.map(item=>item)}

答案 9 :(得分:0)

同样的错误,但不同的场景。我打算将我的自定义功能组件分配给第 3 方模块的 layoutComponent 道具。

错误代码:

customLayout = () => {
// function returning a component
}
//usage:
{customLayout}

修复:

CustomLayout = () => {
// functional component
}
//usage:
<CustomLayout></CustomLayout>

答案 10 :(得分:0)

在设置为 UseState 之前在值上使用 BigNumber 库时出现此错误:

const { toBN } = web3.utils;
...
 setOwner0Balance(toBN(await getBalance(owner0)));

答案 11 :(得分:0)

我遇到了类似的问题,但我的这个问题有效。 My output

但我犯的错误很简单。在我的内容中有两个以上,我忘了将其包装为一个数组。我没有戴卡莉牙套。

import React from 'react'
import {Button} from './Button';
import {Link} from 'react-router-dom'
import './HeroSection.css';

function HeroSection({
    lightBg, topLine, lightText, lightTextDesc, headline, description, 
    buttonLabel, img,alt,imgStart}
) {
    return (
        <>
            <div className={lightBg? 'home__hero-section': 'home__hero-section darkBg'}>
                <div className='container'>
                    <div className="row home__hero-row" 
                    style={{display:'flex', flexDirection:imgStart==='start'?' row-reverse':'row'}}
                    >
                    <div className='col'>
                        <div className='home__hero-text-wrapper'>
                            <div className='topline'>{topLine}</div>
                            <h1 className={lightText? 'heading': 'heading dark'}>{headline}</h1>
 <p className={lightTextDesc? 'home__hero-subtitle': 'home__hero-subtitle dark'}> 
 {description}
 <Link to='/sign-up'>
     <Button buttonSize='btn--wide' buttonColor='blue'>
{buttonLabel}
     </Button>
 </Link>
 </p>
                        </div>

                    </div>

                    <div className='col'>
                        <div className='home__hero-img-wrapper'>
                      <img src={img} alt={alt} className='home_hero-img'/>
                        </div>
                    </div>
                    </div>

                </div>

            </div>

        </>
    );
}

export default HeroSection
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

答案 12 :(得分:0)

我遇到了这个确切的错误。在追踪此问题的根本原因时,我发现 FRONTEND 代码 (React) 正在调用 API 并通过访问该响应的某些属性在页面上显示响应! 所以在这种情况下,有两种情况

  • 在后端的响应中该属性不存在(它会抛出不同的错误) 或
  • 后端响应的属性是一个复杂的对象(Object inside Object),我们的前端 React 组件试图访问它, 但无法读取,因为 React 需要一个 STRING(通过直接访问特定属性,例如 Object.property)或数组。 [本案]

所以我们收到这个错误是因为 React 期待 STRING 但得到了对象(因为你在对象内部传递了 Object)。

请检查发送响应的后端逻辑 (API)。

答案 13 :(得分:0)

使用时刻格式,因为那是日期...转换为日期格式... 时刻(array_list_item.close_date).format("MM-DD-YYYY")}

注意:React 不会在 map 函数中显示这种类型的日期格式

"created_at": "2018-09-18T16:39:22.184Z",

答案 14 :(得分:0)

就我而言,我在 app.js 中添加了一个异步,如下所示。

const App = async() => {
return(
<Text>Hello world</Text>
)
}

但这不是必需的,在测试某些东西时我已经添加了它并且不再需要它。删除它后,如下所示,事情开始工作。

 const App =() => {
    return(
    <Text>Hello world</Text>
    )
}

答案 15 :(得分:0)

当我尝试在接收 props 的子组件上渲染对象时遇到了这个问题。

当我意识到我的代码试图渲染一个对象而不是我试图渲染的对象键的值时,我修复了这个问题。

答案 16 :(得分:0)

有相同的错误,但场景不同。 我的状态为

        this.state = {
        date: new Date()
    }

所以当我在我的类组件中询问它时

p>Date = {this.state.date}</p>

代替

p>Date = {this.state.date.toLocaleDateString()}</p>

答案 17 :(得分:0)

我遇到了同样的问题,但是现在我很高兴解决这个问题。

  1. element[0]
  2. 将此行放入npm i core-js文件的第一行。 index.js

答案 18 :(得分:0)

只是添加到其他选项,我试图通过点方法访问主对象内的嵌套对象,如下所示: this.state.arrayData.CompleteAdress.Location 在这种情况下,位置完整地址中的嵌套对象,这就是为什么我不能简单地用点符号访问它的原因。

  • 因此,如果您遇到同样的问题,请尝试JSON.parse,以便访问嵌套对象,然后进行相应的操作。

答案 19 :(得分:0)

在JavaScript中,虽然数组和集合有些相似,但它们有所不同,但是在这里react需要一个数组。 您需要从array创建一个collection并将其应用。

let homeArray = new Array(homes.length);
let i = 0

for (var key in homes) {
    homeArray[i] =  homes[key];
    i = i + 1;
}

答案 20 :(得分:0)

我今天遇到了相同的错误,但是与此问题中发布的场景相比,场景有所不同。希望以下方案的解决方案可以帮助某人。

下面的render函数足以理解我的情况和解决方案:

render() {
    let orderDetails = null;
    if(this.props.loading){
        orderDetails = <Spinner />;
    }
    if(this.props.orders.length == 0){
        orderDetails = null;
    }
    orderDetails = (
        <div>
            {
                this.props.orders.map(order => (
                <Order 
                    key={order.id}
                    ingredient={order.ingredients}
                    price={order.price} />
                ))
            }
        </div>
    );
    return orderDetails;
}

在上述代码段中:如果return orderDetailsreturn {orderDetails}的形式发送,则尽管'orderDetails'的值(值为<Spinner/>或{{1 }}或与null组件相关的JSX)。

错误描述:react-dom.development.js:57未捕获的不变违规:对象作为React子对象无效(找到:带有键{orderDetails}的对象)。如果要渲染子级集合,请改用数组。

我们无法从render()方法内的返回调用返回JavaScript对象。原因是React期望组件或某个JSX或null可以在UI中呈现,而不是我使用<Order />时试图呈现的JavaScript对象,因此会出现上述错误。