错误消息:TypeError:无法读取未定义的属性“过滤器”

时间:2021-04-14 08:39:01

标签: reactjs mobx

我想在 CarStore.js 中使用 mobx 按名称过滤汽车进行状态管理,但每次运行我的应用程序时,它都会显示一条错误消息 TypeError: Cannot read property 'filter' of undefined 并向我显示此图像:{ {3}}。我不知道出了什么问题?

这是我的代码片段:

CarStore.js

import { observable, computed, makeObservable, action } from "mobx";

class CarStore {
    cars = [
        {
            id: 1,
            carname: "Mercedes Benz",
            model: "E 250D",
            mileage: "350 000",
            year: "1993",
        },

        {
            id: 2,
            carname: "Audi",
            model: "A 5",
            mileage: "150 000",
            year: "2008",
        },

        {
            id: 3,
            carname: "Renault",
            model: "Twingo",
            mileage: "215 000",
            year: "2000",
        },

        {
            id: 4,
            carname: "BMW",
            model: "E34",
            mileage: "78 000",
            year: "1991",
        },

        {
            id: 5,
            carname: "Volvo",
            model: "123 GT (Amazon)",
            mileage: "120 000",
            year: "1967",
        },

        {
            id: 6,
            carname: "Volkswagen",
            model: "Type 2",
            mileage: "35 000",
            year: "1951",
        },

        {
            id: 7,
            carname: "Subaru",
            model: "Crosstrek",
            mileage: "250 000",
            year: "2015",
        },

        {
            id: 8,
            carname: "Mercedes Benz",
            model: "E500",
            mileage: "35 000",
            year: "1994",
        },

        {
            id: 9,
            carname: "Ford",
            model: "Mustang",
            mileage: "264 000",
            year: "1968",
        },

        {
            id: 10,
            carname: "BMW",
            model: "X5",
            mileage: "298 000",
            year: "2001",
        },

        {
            id: 11,
            carname: "Mitsubishi",
            model: "Lancer EVO X",
            mileage: "450 000",
            year: "2013",
        },

        {
            id: 12,
            carname: "Tesla",
            model: "Model 3",
            mileage: "100 000",
            year: "2021",
        },

        {
            id: 13,
            carname: "Cadillac",
            model: "Eldorado",
            mileage: "500 000",
            year: "1986",
        },

        {
            id: 14,
            carname: "Rolls Royce",
            model: "Phantom VIII",
            mileage: "25 000",
            year: "2017",
        },
    ];

    isSorted = false;
    filter = "";

    currentPage = 1;
    carsPerPage = 5;

    indexOfLastCar = this.currentPage * this.carsPerPage;
    indexOfFirstCar = this.indexOfLastCar - this.carsPerPage;

    get currentCars() {
        return this.filteredCars.slice(this.indexOfFirstCar, this.indexOfLastCar);
    }

    get filteredCars() {
        let matchesFilter = new RegExp(this.filter, "i");
        return this.cars
            .filter((car) => car !== null)
            .filter((car) => !this.filter || matchesFilter.test(car.carname));
    }

    get currentSortedCars() {
        return this.sortedCars.slice(this.indexOfFirstCar, this.indexOfLastCar);
    }

    get sortedCars() {
        return this.filteredCars
            .filter((car) => car !== null)
            .slice()
            .sort((a, b) => (a.carname > b.carname ? 1 : -1));
    }

    setPage = (pageNumber) => {
        this.currentPage = pageNumber;
        this.indexOfLastCar = this.currentPage * this.carsPerPage;
        this.indexOfFirstCar = this.indexOfLastCar - this.carsPerPage;
    };

    constructor(cars) {
        makeObservable(this, {
            isSorted: observable,
            cars: observable,
            currentPage: observable,
            carsPerPage: observable,
            indexOfLastCar: observable,
            indexOfFirstCar: observable,
            currentCars: computed,
            filter: observable,
            filteredCars: computed,
            currentSortedCars: computed,
            sortedCars: computed,
            setPage: action,
        });
        this.cars = cars;
    }
}

const store = new CarStore();

export default store;

home.js

import React from "react";

import { inject, observer } from "mobx-react";

class Home extends React.Component {
    filter = (e) => {
        e.preventDefault();
        this.props.CarStore.filter = e.target.value;
    };

    sort = (e) => {
        this.props.CarStore.isSorted = true;
    };

    paginate = (pageNumber) => {
        this.props.CarStore.setPage(pageNumber);
    };
    render() {
        const { filter } = this.props.CarStore;
        const filterAndSort = () => {
            return (
                <>
                    <div>
                        <button>Sort A-Z</button>
                        <form onSubmit={(e) => this.filter(e)}>
                            <input
                                type="text"
                                value="filter"
                                onChange={this.filter.bind(this)}
                            />
                        </form>
                    </div>
                </>
            );
        };

        const openDefaultView = () => {
            return (
                <>
                    <h1>All Cars</h1>
                    {filterAndSort()}
                    <div>
                        {this.props.CarStore.currentCars
                            .filter((car) => car !== null)
                            .map((car) => (
                                <div key={car.id}>
                                    <h2>{car.carname}</h2>

                                    <span>Model: {car.model}</span>

                                    <span>Mileage: {car.mileage}</span>

                                    <span>Year: {car.year}</span>
                                </div>
                            ))}
                    </div>
                </>
            );
        };

        const openSortedView = () => {
            return (
                <>
                    {filterAndSort()}

                    <div>
                        {this.props.CarStore.currentSortedCars.map((car) => (
                            <div key={car.id}>
                                <h2>{car.carname}</h2>

                                <span>Model: {car.model}</span>

                                <span>Mileage: {car.mileage}</span>

                                <span>Year: {car.year}</span>
                            </div>
                        ))}
                    </div>
                </>
            );
        };

        return this.props.CarStore.isSorted ? openSortedView() : openDefaultView();
    }
}

export default inject("CarStore")(observer(Home));

1 个答案:

答案 0 :(得分:1)

当您创建 CarStore 时,您没有传入 cars 数组,因此您的 cars 数组属性会在构造函数中被覆盖。

    const store = new CarStore() // needs cars array

    constructor(cars) {
        makeObservable(this, {
            isSorted: observable,
            cars: observable,
            currentPage: observable,
            carsPerPage: observable,
            indexOfLastCar: observable,
            indexOfFirstCar: observable,
            currentCars: computed,
            filter: observable,
            filteredCars: computed,
            currentSortedCars: computed,
            sortedCars: computed,
            setPage: action,
        });
        this.cars = cars; // <-- undefined
    }
}