簡體   English   中英

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

當我使用React和Flux完成一個Crud應用程序時,我是React的新手,我的錯誤在下面,

在UserList

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">&times;</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方法中引發的錯誤。 我在這里使用flux作為體系結構。當我嘗試向數據中添加新用戶時出現問題。 問題是,當我單擊AddUser組件中的“保存”按鈕時,它保存到我的數據庫中,但是在它需要再次顯示為表列表之后卻拋出錯誤。

我看到的一個問題是,您直接在JSX元素( <td>{user.dob}</td> )內部使用user.dob dobnew Date()react-datepickeronChange事件的直接輸出,兩者都是對象。

這是一個試圖渲染{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> 

這對我來說是這樣的錯誤:

對象作為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是我的最佳猜測。

在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
    })

另外,在React中使用JQuery是一個非常糟糕的主意。 React使用虛擬DOM,因此無法與JQuery配合使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM