React 错误:对象作为 React 子级无效,如果您打算渲染子级集合,请改用数组
Posted
技术标签:
【中文标题】React 错误:对象作为 React 子级无效,如果您打算渲染子级集合,请改用数组【英文标题】:React Error: Objects are not valid as a React child,If you meant to render a collection of children, use an array instead 【发布时间】:2019-06-14 11:17:54 【问题描述】:当我使用 React 和 Flux 完成了一个 crud 应用程序时,我对 react 不熟悉,我收到了这个错误,我的代码如下,
用户列表
import React, Component from "react";
import $ from "jquery";
import UserStore from "../../stores/UserStore";
import * as UserActions from "../../actions/UserActions";
import AddUser from "./AddUser";
$.DataTable = require("datatables.net");
class UserList extends Component
constructor()
super();
this.getUsers = this.getUsers.bind(this);
this.state =
users: UserStore.getAll()
;
this.loadUsers();
componentDidMount()
$(document).ready(function()
$("#example").DataTable(
ordering: true
);
);
componentWillMount()
UserStore.on("change", this.getUsers);
componentWillUnmount()
UserStore.removeListener("change", this.getUsers);
getUsers()
console.log(" get users called");
this.setState(
users: UserStore.getAll()
);
loadUsers()
UserActions.getUsersList();
render()
const userlistitem = this.state.users.map((user, index) => (
<tr key=index>
<th scope="row">index</th>
<td>user.name</td>
<td>user.username</td>
<td>user.email</td>
<td>user.dob</td>
<td>user.address</td>
<td>user.mobile</td>
<td>user.branch</td>
</tr>
));
return (
<div
style=
marginTop: 80,
marginLeft: 150,
marginRight: 150
>
<div className="card text-white bg-info mb-3">
<div className="card-body">
<div className="d-flex justify-content-between">
<h5>User List</h5>
<div>
<button
style=
marginTop: 10
type="button"
className="btn btn-light "
data-toggle="modal"
data-target="#exampleModalCenter"
>
Add New User
</button>
</div>
</div>
</div>
</div>
<table id="example" className="table table-bordered table-striped ">
<thead className="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">User Name</th>
<th scope="col">Email</th>
<th scope="col">DOB</th>
<th scope="col">Address</th>
<th scope="col">Mobile</th>
<th scope="col">Branch</th>
</tr>
</thead>
<tbody>userlistitem</tbody>
</table>
<AddUser />
</div>
);
export default UserList;
添加用户
import React, Component from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import "../../css/datepicker.css";
import * as UserActions from "../../actions/UserActions";
class AddUser extends Component
constructor(props)
super(props);
this.state =
branch: "",
name: "",
username: "",
mobile: "",
email: "",
address: "",
dob: new Date()
;
this.handleInputChange = this.handleInputChange.bind(this);
this.handledatepickerchange = this.handledatepickerchange.bind(this);
handleInputChange(event)
const target = event.target;
const value = target.value;
const name = target.name;
this.setState( [name]: value );
handledatepickerchange(event)
this.setState( dob: event );
createUser = () =>
console.log("this is:", this);
const user =
branch: this.state.branch,
name: this.state.name,
username: this.state.username,
mobile: this.state.mobile,
email: this.state.email,
address: this.state.address,
dob: this.state.dob
;
UserActions.createNewUser(user);
this.setState(
branch: "",
name: "",
username: "",
mobile: "",
email: "",
address: "",
dob: new Date()
);
;
render()
return (
<div
className="modal fade"
id="exampleModalCenter"
tabIndex="-1"
role="dialog"
aria-labelledby="exampleModalCenterTitle"
aria-hidden="true"
>
<div className="modal-dialog modal-dialog-centered" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalCenterTitle">
Add New User
</h5>
<button
type="button"
className="close"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
<div className="input-group mb-3">
<input
name="name"
type="text"
className="form-control"
placeholder="Name"
aria-label="Name"
aria-describedby="button-addon2"
value=this.state.name
onChange=this.handleInputChange
/>
</div>
<div className="input-group mb-3">
<input
name="username"
type="text"
className="form-control"
placeholder="User Name"
aria-label="User Name"
aria-describedby="button-addon2"
value=this.state.username
onChange=this.handleInputChange
/>
</div>
<div className="input-group mb-3">
<input
name="email"
type="email"
className="form-control"
placeholder="Email"
aria-label="Email"
aria-describedby="button-addon2"
value=this.state.email
onChange=this.handleInputChange
/>
</div>
<div className="input-group mb-3">
<input
name="address"
type="text"
className="form-control"
placeholder="Address"
aria-label="Address"
aria-describedby="button-addon2"
value=this.state.address
onChange=this.handleInputChange
/>
</div>
<div className="input-group mb-3">
<input
name="branch"
type="text"
className="form-control"
placeholder="Branch"
aria-label="Branch"
aria-describedby="button-addon2"
value=this.state.branch
onChange=this.handleInputChange
/>
</div>
<div className="input-group mb-3">
<DatePicker
name="dob"
type="text"
className="form-control"
placeholder="DOB"
aria-label="DOB"
aria-describedby="button-addon2"
selected=this.state.dob
onChange=this.handledatepickerchange
/>
<p
style=
marginTop: "5px",
fontWeight: "200",
marginLeft: "10px"
>
Date of Birth(dd/mm/yyyy)
</p>
</div>
<div className="input-group mb-3">
<input
name="mobile"
type="number"
className="form-control"
placeholder="Mobile No."
aria-label="Mobile No."
aria-describedby="button-addon2"
value=this.state.mobile
onChange=this.handleInputChange
/>
</div>
</div>
<div className="modal-footer">
<br />
<br />
<button
type="button"
className="btn btn-secondary"
data-dismiss="modal"
>
Close
</button>
<button
type="button"
className="btn btn-primary"
data-dismiss="modal"
onClick=this.createUser
>
Save
</button>
</div>
</div>
</div>
</div>
);
export default AddUser;
动作
import dispatcher from "../dispatcher/dispatcher";
import BASE_URL from "../utils/AppConstants";
export function getUsersList()
console.log("getting the data! ");
fetch(BASE_URL + "/users")
.then(res => res.json())
.then(
result =>
console.log("res " + result);
dispatcher.dispatch( type: "RECEIVE_USERS", users: result );
,
// Note: it's important to handle errors here instead of a catch() block so that
// we don't swallow exceptions from actual bugs in components.
error =>
// here manage error and close loading;
console.log("getting error " + error);
);
export function createNewUser(user)
console.log("post the data!");
fetch(BASE_URL + "/saveuser",
method: "POST",
headers:
Accept: "application/json",
"Content-Type": "application/json"
,
body: JSON.stringify(user)
)
.then(res => res.json())
.then(
result =>
dispatcher.dispatch( type: "CREATE_USER", newUser: user );
,
// Note: it's important to handle errors here instead of a catch() block so that
// we don't swallow exceptions from actual bugs in components.
error =>
// here manage error and close loading;
console.log("getting error " + error);
);
商店
import EventEmitter from "events";
import dispatcher from "../dispatcher/dispatcher";
class UserStore extends EventEmitter
constructor()
super();
dispatcher.register(this.handleActions.bind(this));
this.users = [
branch: "19",
name: "Javcbvcsim11",
username: "zxcv",
mobile: "5645654",
email: "demo@gmail.com111",
address: "Demo vcbvcbAddress1",
dob: "2020-11-06T00:00:00.000+0000"
];
createUser(newUser)
this.users.push(newUser);
console.log("new users lenght " + this.users.lenght);
this.emit("change");
getAll()
return this.users;
handleActions(action)
switch (action.type)
case "RECEIVE_USERS":
this.users = action.users;
this.emit("change");
break;
case "CREATE_USER":
this.createUser(action.newUser);
break;
export default new UserStore();
我不知道这里发生了什么问题。当检查堆栈溢出时,我知道这是迭代数据的问题。但我已经这样做了。即使错误仍然存在。如果有人可以提供帮助,那将是非常可观的。 setState 方法中抛出的错误。我在这里使用通量作为架构。当我尝试将新用户添加到我的数据时会出现问题。实际上,当我将它添加到数据库时没有任何问题。问题是当我单击 AddUser 组件中的保存按钮时,它会保存到我的数据库中,但是在它需要再次显示为表格列表但抛出错误之后。
【问题讨论】:
【参考方案1】:我可以看到的一个问题是您在 JSX 元素 (<td>user.dob</td>
) 中直接使用了user.dob
。 dob
要么是new Date()
,要么是react-datepicker
的onChange
事件的直接输出,两者都是对象。
这是一个试图渲染new Date()
的虚拟组件。
const App = ( text ) => <p>text</p>;
// Passing Date object.
ReactDOM.render(<App text=new Date() />, document.getElementById("app"));
<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>
<div id="app"></div>
这对我来说会导致类似this 的错误:
对象作为 React 子级无效(发现时间:2019 年 1 月 21 日星期一 12:37:56 GMT+0530(印度标准时间))。
这意味着你将一个对象,而不是一个字符串作为子元素传递给 JSX 元素。
注意这是如何工作的:
const App = ( text ) => <p>text</p>;
// Passing stringified Date object.
ReactDOM.render(<App text=new Date().toString() />, document.getElementById("app"));
<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>
<div id="app"></div>
我将一个字符串作为p
JSX 元素的子元素传递。您需要做类似的事情并确保没有对象通过。
实际上,由于您没有发布整个错误,因此很难说是哪个条目导致了错误。但是,user.dob
是我的最佳猜测。
【讨论】:
谢谢老兄。这就是问题【参考方案2】:在 React 中迭代对象是很棘手的。通常你想使用Object.entries
/Object.values
/Object.keys
然后.map
。这将获取对象并创建一个数组,然后您可以使用.map
遍历该对象。 .map
对对象不起作用,因为它是一个数组函数,所以你必须先把你的对象变成一个数组。 .map
函数将允许您在 React 中进行迭代而不会出现该错误:
this.state =
branch: "",
name: "",
username: "",
mobile: "",
email: "",
address: ""
// Not in your constructor
let myObj = this.state;
Object.entries(myObj).map(item =>
// Successfully iterates, do what you need to do in here
)
另外,将 JQuery 与 React 结合使用是一个非常糟糕的主意。 React 使用虚拟 DOM,不能很好地与 JQuery 配合使用。
【讨论】:
以上是关于React 错误:对象作为 React 子级无效,如果您打算渲染子级集合,请改用数组的主要内容,如果未能解决你的问题,请参考以下文章
错误:对象无效作为React子级(Axios和openweathermap API)
Apollo 客户端错误,对象作为 React 子级无效(发现:[object Promise])
对象作为 React 子级无效。如果您打算渲染一组孩子,请改用数组 - FlatList
对象作为 React 子级无效如果您要渲染子级集合,请改用数组