TypeError:无法读取View.render上未定义的属性“ map”(app.js:70994)

时间:2019-10-06 16:37:35

标签: reactjs

我使用laravel编写了一个简单的Crud应用程序。 添加功能可以正常运行,但是我无法查看记录,但出现错误

TypeError:无法读取未定义的属性“ map” 如果有人可以帮助,将不胜感激 这是我的代码

Example.js

import React, {Component} from 'react';


import ReactDOM from 'react-dom';
import Header from "./Header";
import Footer from "./Footer";

export default class Example extends Component {
render() {
    return (
        <div className="container">
            <Header/>
           I love React...
            <Footer/>
        </div>
    );
}
}

if (document.getElementById('example')) {
ReactDOM.render(<Example/>, document.getElementById('example'));
}

Header.js

import React, {Component} from 'react';

// import {Link, Route} from "react-router-dom";
import {BrowserRouter as Router, Link, Route} from "react-router- 
dom";


import View from "./View";
import Add from "./Add";
import Edit from "./Edit";


export default class Header extends Component {
render() {
    return (


        <div className="pos-f-t">
            <div className="collapse" 
id="navbarToggleExternalContent">
                <div className="bg-dark p-4">
                    <h4 className="text-white">Collapsed 
content</h4>
                    <span className="text-muted">Toggleable via 
the navbar brand.</span>
                </div>
            </div>
            <nav className="navbar navbar-dark bg-dark">




            </nav>
        <Router>
            <Link to="/add" className="btn btn-dark" >Add</Link>
            <Link to="/view" className="btn btn-dark" >View</Link>
            <Route exact path="/add" component={Add}/>
            <Route exact path="/view" component={View}/>
            <Route exact path="/edit/:id" component={Edit}/>
        </Router>
        </div>


    );
}
}

View.js

import React, {Component} from 'react';
import axios from 'axios';
import {BrowserRouter as Router, Link, Route} from "react-router- 
dom";
// import {Link} from "react-router-dom";

// this is used for pagination
import Pagination from "react-js-pagination";
//end pagination here

export default class View extends Component {


constructor() {

    super();
    this.state = {

        rssreads: [],

        // this is used for pagination
        activePage: 1,
        itemsCountPerPage: 1,
        totalItemsCount: 1,
        pageRangeDisplayed: 5

        //end pagination here
    }


    this.handlePageChange = this.handlePageChange.bind(this);
}


//didmount is used to render data
componentDidMount() {
    axios.get('/view').then(response => {
        this.setState({
            rssreads: response.data.data,
            activePage: response.data.current_page,
            itemsCountPerPage: response.data.per_page,
            totalItemsCount: response.data.total,

        });

    });
}

handlePageChange(pageNumber) {
    console.log(`active page is ${pageNumber}`);
    this.setState({activePage: pageNumber});

    axios.get('/view?page=' + pageNumber).then(response => {
        this.setState({
            rssreads: response.data.data,
            itemsCountPerPage: response.data.per_page,
            totalItemsCount: response.data.total,
            activePage: response.data.current_page,


        });

    });
}

//ondelete function to delte specific record
onDelete(url_id) {

    axios.delete('delete/' + url_id).then(response => {


        // this code is for live updating data after delete
        var url = this.state.rssreads;

        for (var i = 0; i < url.length; i++) {

            if (url[i].id === url_id) {
                url.splice(i, 1);

                this.setState({rssreads: url});
            }
        }


    });

}


render() {
    return (

        <div>
            <table className="table">
                <thead>
                <tr>

                    <th>Title</th>
                    <th>Content</th>
                    <th>Link</th>
                    <th>Publish</th>
                    <th>URL</th>
                    <th>Action</th>
                </tr>
                </thead>
                <tbody>


                {

                    this.state.rssreads.map(rssreads => {

                        return (
                            <tr>
                                <td>{rssreads.title}</td>
                                <td>{rssreads.content}</td>
                                <td>{rssreads.link}</td>
                                <td>{rssreads.publish}</td>
                                <td>{rssreads.url}</td>
                                <td>
                                    <Link to= 
   {`/edit/${rssreads.id}`}>Edit</Link>
                                    <a href="#" onClick= 
   {this.onDelete.bind(this, rssreads.id)}>Delete</a></td>
                            </tr>
                        )
                    })
                }
                </tbody>
            </table>


            <div className="pagination justify-content-center">
                <Pagination
                    activePage={this.state.activePage}
                    itemsCountPerPage= 
   {this.state.itemsCountPerPage}
                    totalItemsCount={this.state.totalItemsCount}
                    pageRangeDisplayed= 
   {this.state.pageRangeDisplayed}
                    onChange={this.handlePageChange}
                    itemClass='page-item'
                    linkClass='page-link'
                />
            </div>


        </div>


    );
   }
 }

This error I got and view page is disappeared

2 个答案:

答案 0 :(得分:1)

this.state.rssreads.map(rssreads => {这是您在谈论的有关***的电话!

未定义。即使您在构造函数中将其设置为空数组[]。那可能只意味着一件事。您正在将它固定在某个地方。在这种情况下,找到罪魁祸首的最快方法是 CTRL + f 并搜索 setState

您会很快找到罪魁祸首。

但是可能是什么问题!!!状态设置错误。只设置一个,没有其余的!反应 setState()方法每次检查孔的状态 !!

例如在您的代码中

handlePageChange(pageNumber) {
    console.log(`active page is ${pageNumber}`);
    this.setState({activePage: pageNumber}); // <------ that's a mistake !!!!!!!!!!

    axios.get('/view?page=' + pageNumber).then(response => {
        this.setState({
            rssreads: response.data.data,
            itemsCountPerPage: response.data.per_page,
            totalItemsCount: response.data.total,
            activePage: response.data.current_page,


        });

    });
}

您应该这样做:

  this.setState({...this.state, activePage: pageNumber});

复制所有状态并仅覆盖一个属性。

但是,如果我想重置所有状态,包括您的代码中的rssreads !!!!!

  this.setState({activePage: pageNumber, rssreads: []}); 

如果其余的都可以不确定,那就可以了! (并且您一一重置属性!!!!)

如果其余部分必须保留这些值:

  this.setState({...this.state, activePage: pageNumber, rssreads: []}); 

最后,如果有很多属性,而我又不想一个接一个地检查它们,那该怎么办。

答案:将建立一个函数,让您轻松创建新状态。您可以考虑一下。那样会很好。但是对于实践来说,有很好的库。我最喜欢的是沉浸式。所以检查一下。

https://www.npmjs.com/package/immer

这里有个例子:

import immerProduce from 'immer';

store.dispatch(setGlobalStates(
    immerProduce(globalStates, (draft) => {
        draft.loadingSpinner.show = true;
    })
));

我在redux中使用它。但重要的是,动作创建者(或只是方法)setGlobalStates期待着新的状态! 使用沉浸式。您在globalStates处传递了旧状态。然后,您具有代表当前状态的回调和草稿。您以正常方式进行更改。正常变异(以变异的方式)。然后 immer 将其找出并返回新的不可变状态。凉。没有麻烦和简单。 您在需要时使用它。并非总是需要。

最近,有时罪魁祸首只是在获取过程中。当您获得数据时,您将得不到很好的结果。因此,您总是要怀疑并在课程结束时检查是否有任何效果!!!!!!!

您总是可以使用以下内容:

myVar || defaultValue // if the first undefined the second will take place

myCondition ? thisV: orthis

myList || []

// or simply conditions
thisV && thisB && thisL // if the first is true it evaluate the next one. if true too it will return the last. If one is false the whole thing is false!

if () {} else {}


// in expression and variable binding  you can even do that!

<div>{
(() => {   // <-------------------- an IIFE (Immediately Invoked Function Expression)
    // my cool processing
    return whatToReturn;
})()
}</div>

传播算子

    this.setState({ 
        ...this.state, 
        rssreads: myData || [], 
        otherProp: oneAfterAnotherButOnlyTheOneThatYouNeedToReset,
        //......
    );

...是价差运算符。在这种用法下,可以轻松合并!

所以您说的是抓住所有旧状态,并覆盖或添加该状态!

等效为

Object.assign({}, this.state, {rssreads: myData, ..}); 

参考:

还有一个注释myData || []。意思是如果第一个是真实值,那就接受它。如果不是,则使用第二个值!因此,如果myData未定义,则将使用[]。 myData || []的等效项是myData ? myData : []

这样,答案就更完整了。

答案 1 :(得分:0)

由于@“ Mohamed Allal”建议调试设置“ rssreads”状态的位置

快速修复:尝试

{
      this.state.rssreads &&
        this.state.rssreads.map(rssreads => {
          return (
            <tr>
              <td>{rssreads.title}</td>
              <td>{rssreads.content}</td>
              <td>{rssreads.link}</td>
              <td>{rssreads.publish}</td>
              <td>{rssreads.url}</td>
              <td>
                <Link to={`/edit/${rssreads.id}`}>Edit</Link>
                <a href="#" onClick={this.onDelete.bind(this, rssreads.id)}>
                  Delete
                </a>
              </td>
            </tr>
          );
        });
    }