【问题标题】:ReactJS sort by Asc/Desc not rendering sorted list from nested componentReactJS 按 Asc/Desc 排序不从嵌套组件呈现排序列表
【发布时间】:2021-05-17 21:22:15
【问题描述】:

项目概述

我目前正在学习 ReactJS,并正在创建一个 Pokedex 应用程序,该应用程序允许用户按特定属性(名称、类型、hp 等)对 Pokemon 对象进行排序。最终产品应该有一个按口袋妖怪名称过滤的搜索输入、一个用于排序标准的下拉选择器,以及一个用于升序排序和降序排序的按钮。被跟踪的状态是 searchQuery、sortBy、sortSelected 和 pokeData(我的数据文件)。

完整代码可以在这里查看:https://github.com/julianne-vela/Pokedex-React/tree/dev

文件结构: SearchPage.js > SideBar.js > SortMenu.js

问题


SortMenu 中的 onClick 按钮未呈现已排序的口袋妖怪列表。

预期结果:单击 SortMenu 中的 Asc/Desc 按钮 -> Pokemon 列表根据下拉列表中选择的条件按排序顺序呈现,并单击 Asc/Desc 按钮。

实际结果:下拉列表正在更新状态并选择了正确的排序标准,但按钮在单击时不会触发任何操作。

我尝试过的


在整个项目中使用解构道具

const {
    sortBy,
    sortSelected,
} = this.state

目前将 SearchPage.js 中的以下 props 传递给子 SideBar.js:

sortByValues={sortBy} // Array of sort criteria options stored in state
sortSelected={sortSelected} // Currently selected sort criteria from drop-down
handleSortSelected={this.handleSortSelected} // event handler to update state with currently selected sort criteria
sortAsc={this.sortAsc} // function to trigger Asc sort onClick
sortDesc={this.sortDesc} // function to trigger Asc sort onClick

SortMenu.js 代码

import React, { Component } from 'react';

export default class SortMenu extends Component {
    render() {
        const {
            sortByValues,
            handleSortSelected,
            sortAsc,
            sortDesc,
        } = this.props

        const options = sortByValues.map(option => <option value={option} key={option}>{option}</option>)

        return (
            <aside>
                {/* DropDown Sort By */}
                <select className='dropdown'
                    onChange={handleSortSelected}>
                    {options}
                </select>

                {/* Sort Ascending/Descending Buttons */}
                <button className='sortBtn' value='ascending' onClick={sortAsc}>Ascending</button>
                <button className='sortBtn' value='descending' onClick={sortDesc}>Descending</button>

            </aside >
        )
    }
}

我觉得重要的是要注意我们正在使用严格的类组件,因此在这个项目中没有使用构造函数(props)。相反,我始终使用箭头函数在需要的地方隐式绑定它。

重申我的目标:我需要根据在下拉列表中选择的排序标准以及单击的上升/下降按钮来动态呈现口袋妖怪列表。该列表应更新 onClick。

我已经为此工作了 3 天,并且经历了如此多的排序功能迭代,以至于我什至无法再看清楚了。我认为这可能是一个简单的疏忽,因为我正在编写大量代码,而且这是一种新语言(我已经精通 Vanilla JS)。

这里的任何指导都将不胜感激,因为此时我真的很困惑。我不知道还可以尝试什么来呈现排序列表。

更新

另外,如果我要为 Asc/Desc 创建一个切换按钮而不是两个单独的按钮会更容易吗?

谢谢!

更新 2

目前,我在 SearchPage.js 组件中调用的模块组件中呈现我的口袋妖怪对象。这是口袋妖怪列表的代码:

export default class PokemonList extends Component {


    render() {
        const { filteredPokemon } = this.props

        return (
            <content className='pokemon-list float'>
                {filteredPokemon.map(pokeObject =>
                    <PokeItem
                        key={pokeObject._id}
                        pokeImage={pokeObject.url_image}
                        pokeName={capFirstLetter(pokeObject.pokemon)}
                        pokeType={capFirstLetter(pokeObject.type_1)}
                        pokeHp={pokeObject.hp}
                        pokeAtt={pokeObject.attack}
                        pokeDef={pokeObject.defense}
                    />)}
            </content>
        );
    }
}

这是从我在 SearchPage.js 上的过滤方法中提取过滤后的口袋妖怪:

const filteredList = pokeData.filter(pokeObject => {
            return pokeObject['pokemon'].includes(this.state.searchQuery) || pokeObject['type_1'].includes(tFilterSelected);
        });

为了对项目进行排序,我使用了两个单独的箭头函数。这些位于 SearchPage.js 组件的第一部分(渲染和返回之外):

sortAsc = () => {
        this.setState(prevState => {
            this.state.pokeData.sort((a, b) => (a[this.state.sortSelected] - b[this.state.sortSelected]))
        })
    }

    sortDesc = () => {
        this.setState(prevState => {
            this.state.pokeData.sort((a, b) => (b[this.state.sortSelected] - a[this.state.sortSelected]))
        })
    }

更新 3

将项目添加到 CodeSandbox。可以在这里查看:https://codesandbox.io/s/pokedex-react-crflb

【问题讨论】:

  • 您能否说明您是如何呈现已排序项目的?
  • @DrewReese 我想我包括了你的要求。让我知道这是否不清楚或者我是否遗漏了其他任何内容。谢谢!
  • @Julianne 你能和你的代码分享一个CodeSandbox URL吗?
  • @ArunKumarMohan 我以前从未使用过那个平台,但这真的很酷!我已将 CodeSandbox URL 添加到我的帖子中。
  • @Julianne 让我看看。

标签: reactjs sorting


【解决方案1】:

减去参数的比较器函数可以很好地对数字进行排序,但在字符串上会失败,因为它会返回 NaN。

sortAsc = () => {
  const { pokeData, sortSelected } = this.state
  this.setState({
    pokeData: [...pokeData].sort((a, b) => {
      if (a[sortSelected] > b[sortSelected]) {
        return 1
      }

      if (a[sortSelected] < b[sortSelected]) {
        return -1
      }

      return 0
    })
  })
}

sortDesc = () => {
  const { pokeData, sortSelected } = this.state
  this.setState({
    pokeData: [...pokeData].sort((a, b) => {
      if (a[sortSelected] > b[sortSelected]) {
        return -1
      }

      if (a[sortSelected] < b[sortSelected]) {
        return 1
      }

      return 0
    })
  })
}

Working CodeSandbox

【讨论】:

  • 我的话!非常感谢你!我已经为此绞尽脑汁很久了,之前我已经很接近了!我之前基本上已经写出了这个确切的函数,但我没有使用 key:value 语法,所以它不起作用!我非常感谢你!再次感谢您!
猜你喜欢
  • 2021-10-07
  • 2014-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-05
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多