繁体   English   中英

单击两次时如何从状态切换排序数组数据?

[英]How to toggle sort array data from state when click twice?

创建了多个功能,可按等级,等级和点击标题进行排序。 如果可能的话,我想做的是按实例“切换”电影标题ASC顺序并第二次单击“ DESC”。 尝试创建默认布尔值isSorted: false并基于单击将isSorted设置为true,如果是,则从B到A进行排序。

我现在与React一起工作了1个月,如果有人可以给我一些积极的反馈意见,以便使我在React方面变得更好,我将不胜感激。

我的React代码:

import React, { Component } from 'react';

import { getMovies } from '../services/fakeMovieService';

class Movies extends Component {
    state = {
        isSorted: false,
        movies: getMovies(),
        isDisabled: true,
    };

    // Display all movies but not the one selected.
    handleDelete = movie => {
        this.setState({
            movies: this.state.movies.filter(m => m._id !== movie._id),
            isDisabled: false,
        });

        console.log(`Movie ${movie.title} deleted.`);
    };

    // Sort all video's by title
    sortByTitle = () => {
        this.setState({
            movies: this.state.movies.sort((a, b) =>
                a.title > b.title ? 1 : -1
            ),
            isDisabled: false,
        });

        console.log('sorted by title');
    };

    // Sort all video's by genre
    sortByGenre = () => {
        this.setState({
            movies: this.state.movies.sort((a, b) =>
                a.genre.name > b.genre.name ? 1 : -1
            ),
            isDisabled: false,
        });
        console.log('sorted by genre.');
    };

    // sort all video's by stock size
    sortByStock = () => {
        this.setState({
            movies: this.state.movies.sort(
                (a, b) => a.numberInStock - b.numberInStock
            ),
            isDisabled: false,
        });

        console.log('sorted by stock size.');
    };

    // Sort all video's by rating score
    sortByRating = () => {
        this.setState({
            movies: this.state.movies.sort(
                (a, b) => a.dailyRentalRate - b.dailyRentalRate
            ),
            isDisabled: false,
        });

        console.log('sorted by rating sore.');
    };

    // Add class to the reset button based on the current filter state.
    resetButtonClass = () => {
        let btnClass = 'btn btn-sm btn-';
        btnClass += this.state.isDisabled ? 'warning' : 'primary';
        return btnClass;
    };

    // Reset the video's filter
    resetFilter = () => {
        this.setState({
            movies: [...getMovies()],
            isDisabled: true,
        });

        console.log('Reset movies database.');
    };

    render() {
        const { length: count } = this.state.movies;

        // Check if there are movies available.
        if (count === 0)
            return (
                <React.Fragment>
                    <h4>There are no movies in the database.</h4>
                    <button
                        type="button"
                        onClick={this.resetFilter}
                        className="btn btn-primary btn-sm">
                        Reset
                    </button>
                </React.Fragment>
            );

        return (
            <React.Fragment>
                <h5 className="pb-2">Showing {count} in the database.</h5>
                <table className="table table-striped table-dark">
                    <thead>
                        <tr>
                            <th onClick={this.sortByTitle}>Title</th>
                            <th onClick={this.sortByGenre}>Genre</th>
                            <th onClick={this.sortByStock}>Stock</th>
                            <th onClick={this.sortByRating}>Rate</th>
                            <th scope="col">
                                <button
                                    onClick={this.resetFilter}
                                    className={this.resetButtonClass()}
                                    disabled={this.state.isDisabled && true}>
                                    Reset filter
                                </button>
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.state.movies.map(movie => {
                            const {
                                _id,
                                title,
                                genre,
                                numberInStock,
                                dailyRentalRate,
                            } = movie;

                            return (
                                <tr key={_id}>
                                    <th>{title}</th>
                                    <td>{genre.name}</td>
                                    <td>{numberInStock}</td>
                                    <td>{dailyRentalRate}</td>
                                    <td>
                                        <button
                                            onClick={() =>
                                                this.handleDelete(movie)
                                            }
                                            className="btn btn-danger btn-sm">
                                            Delete
                                        </button>
                                    </td>
                                </tr>
                            );
                        })}
                    </tbody>
                </table>
            </React.Fragment>
        );
    }
}

export default Movies;

PS是我的代码干净并且可以理解吗?

提前致谢。

问候,尼诺

你可以这样

这里的想法是基于sorted键的值,我们设置排序函数的返回值,然后切换sort键的值

 let obj = { data: [5,4,3,2,1,0], sorted: 'dsc' } // let first click happended obj.data.sort((a,b)=> obj.sorted === 'asc' ? ba : ab) obj.sorted = obj.sorted === 'asc' ? 'dsc' : 'asc' console.log(obj.data) // let second click happended obj.data.sort((a,b)=> obj.sorted === 'asc' ? ba : ab) obj.sorted = obj.sorted === 'asc' ? 'dsc' : 'asc' console.log(obj.data) 

你能适应你sortByTitle方法来改变的价值isSorted ,然后有条件地对它进行排序上升或下降。

sortByTitle = () => {
        let movies = this.state.movies
        let isSorted = !this.state.isSorted

        if (!this.state.isSorted){
            movies = movies.sort((a, b) =>
                a.title > b.title ? 1 : -1
            )
        } else {
            movies = movies.sort((a, b) =>
                a.title > b.title ? -1 : 1 
            )
        }

        this.setState({
            isDisabled: false,
            movies, isSorted
        });

        console.log('sorted by title');
    };

您应在状态下存储尽可能少的数据。 您不需要将电影存储在状态中,因为您始终可以从getMoviesisSortedisDisabled计算电影:

function computeMovies(sort, isDisabled) {
   switch(sort) {
       case 'TITLE_ASC':
          return getMovies().sort(....);
       case 'TITLE_DESC':
          return getMovies().sort(....);
       ... more cases here
   }
}

render() {
   const movies = computeMovies(this.state.sort, this.state.isDisabled);

   return ...
}

将排序逻辑放在纯函数中可以更轻松地进行测试和推理。

应用相同的原则来设置sort

function computeSort(sort) {
   switch(state) {
      case 'TITLE_ASC':
         return 'TITLE_DESC'
     ... more cases here
   }
}
 sort = (sortProp) => {
    switch(sortProp) {
       case 'TITLE':
         this.setState({
            sort: this.state.sort === 'TITLE_ASC' ? 'TITLE_DESC' : 'TITLE_ASC';
         });
       ... more cases here
    }
 }


 render() {
 <th onClick={ () => this.sort('TITLE')}>Title</th>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM