首页 > 解决方案 > 按名称或 ID 排序的资产

问题描述

我有一个集合列表(在我的屏幕左侧),只要单击集合(屏幕右侧)就会显示它们的资产。我现在正在尝试添加基于选择标签的资产排序功能(请参阅渲染)。默认情况下,资产应按名称排序,但下拉菜单允许用户在“按 id 排序”和“按名称排序”之间切换。我在 handleAssetsClick() 中创建资产。我遇到的问题是我无法在不重新单击集合并因此激活 handleAssetsClick() 的情况下更新资产。handleAssetsClick 很重要,因为它可以选择哪些资产是每个集合的一部分。

关于如何解决这个问题的任何建议?


import React from 'react';
import './App.css';
import {collections} from "./data.js"
import {assets} from "./data.js"
import {FaStar} from "react-icons/fa"

class App extends React.Component {
    constructor() {
        super()

        this.state = {
           collectionsarr: collections,
           assetsarr: assets,
           clickedassets: []
        }
    }

    handleAssetsClick(id){
      const clickedassetsdata = this.state.assetsarr.filter(asset => asset.collectionId === id)
      this.setState({
        clickedassets: clickedassetsdata
      })
    }

    makeMaster(idclick){
      const themasteridnr = this.state.clickedassets.filter(masterpot => masterpot.id === idclick)[0].id
      const newcollections = this.state.collectionsarr.slice()
      const index = this.state.clickedassets.filter(masterpot => masterpot.id === idclick)[0].collectionId - 1
      newcollections[index].masterAssetId = themasteridnr
      this.setState({   
        ...this.state,
        collectionsarr: newcollections
      })
    }

    getAssetPath(masterAssetId){
      const asset = this.state.assetsarr.find(x => x.id === masterAssetId)
      return asset ? require(`./${asset.path}`) : ''
    }

    getMasterId(assetnr){
      let idresult = this.state.collectionsarr.find(collection => collection.masterAssetId === assetnr)
      if(typeof idresult === "undefined"){
        return -1
      } else if (typeof idresult !== "undefined"){
        return idresult.masterAssetId
      } 
    }
  
  render(){
  return (
          <div className="App">
            <h1>Coding challenge</h1>
            
            <label>Sort assets by:</label>
            <select name="sorting">
                <option value="sortbyname">NAME</option>
                <option value="sortbyid">ID</option>
            </select>
            
            
            <div className="left">
              {this.state.collectionsarr.map(element => 
                <div key={element.id}>
                  <p onClick={()=>this.handleAssetsClick(element.id)}>{element.name}</p>
                  <img src={this.getAssetPath(element.masterAssetId)} alt="pic"/>
                  <br></br>
                  <br></br> 
                </div>
              )}
            </div>

            <div className="right">
                {this.state.clickedassets.map(asset => 
                  <div key={asset.id}>
                    <img src={require(`./${asset.path}`)} alt="pic"/>
                    <p>{asset.name}</p>
                    <p>{asset.id}</p>
                    {asset.id !== this.getMasterId(asset.id) && <button onClick={() => this.makeMaster(asset.id)}>Make master!</button> }
                    {asset.id === this.getMasterId(asset.id) && <FaStar />}
                    <br></br>
                    <br></br>
                  </div>
                )}
            </div>
          </div>
        )
  }
}

export default App

数据.js

const collections = [
    {
        id: 1,
        name: "The Simpsons",
        masterAssetId: 13,
        tags: {
            name: "Cartoon",
            subTag: {
                name: "Simpsons family",
                subTag: {
                    name: "2014",
                },
            },
        },
    },
    {
        id: 2,
        name: "Super heroes",
        masterAssetId: 24,
        tags: {
            name: "DC Super heroes",
            subTag: {
                name: "2014",
            },
        },
    },
    {
        id: 3,
        name: "Toy story",
        masterAssetId: 31,
        tags: {
            name: "Disney",
            subTag: {
                name: "Pixar",
                subTag: {
                    name: "Original movie",
                    subTag: {
                        name: "2010",
                    },
                },
            },
        },
    },
    {
        id: 4,
        name: "Ninjago",
        masterAssetId: 42,
        tags: {
            name: "Ninja",
            subTag: {
                name: "Secret Ninja Force",
                subTag: {
                    name: "2017",
                },
            },
        },
    },
];

const assets = [
    {
        id: 11,
        name: "Homer Simpson",
        path: "Homer.jpg",
        collectionId: 1,
    },
    {
        id: 12,
        name: "Lisa Simpson",
        path: "Lisa.jpg",
        collectionId: 1,
    },
    {
        id: 13,
        name: "Bart Simpson",
        path: "Bart.jpg",
        collectionId: 1,
    },
    {
        id: 14,
        name: "Marge Simpson",
        path: "Marge.jpg",
        collectionId: 1,
    },
    {
        id: 15,
        name: "Grampa Simpson",
        path: "Grampa.jpg",
        collectionId: 1,
    },
    {
        id: 16,
        name: "Maggie Simpson",
        path: "Maggie.jpg",
        collectionId: 1,
    },
    {
        id: 21,
        name: "Green Lantern",
        path: "Green lantern.jpg",
        collectionId: 2,
    },
    {
        id: 22,
        name: "Flash",
        path: "Flash.jpg",
        collectionId: 2,
    },
    {
        id: 23,
        name: "Batman",
        path: "Batman.jpg",
        collectionId: 2,
    },
    {
        id: 24,
        name: "Superman",
        path: "Superman.jpg",
        collectionId: 2,
    },
    {
        id: 31,
        name: "Buzz Lightyear",
        path: "Buzz.jpg",
        collectionId: 3,
    },
    {
        id: 32,
        name: "Alien",
        path: "Alien.jpg",
        collectionId: 3,
    },
    {
        id: 41,
        name: "Spinjitzu training Nya",
        path: "Nya.jpg",
        collectionId: 4,
    },
    {
        id: 42,
        name: "Master Wu",
        path: "Wu.jpg",
        collectionId: 4,
    },
    {
        id: 43,
        name: "Lloyd",
        path: "Lloyd.jpg",
        collectionId: 4,
    },
];

export {collections}
export {assets}

标签: javascriptreactjs

解决方案


onChange处理程序添加到将排序设置为状态的选择。如果状态中已经有一个“clickedassets”数组,您可以相应地更新它。除了内容之外,您可能还需要跟踪单击的 id,以便您可以重新运行您正在执行的任何过滤等。

// define whatever sort functions you need
const sort = {
  'name': (a, b) => localeCompare(a.name, b.name), // or whatever
  'id': (a, b) => localeCompare(a.id, b.id),
}

// save sort selection in state and re-trigger handleAssetsClick
onSortChange({target: {value}}) {
  const {selectedId} = this.state;
  this.setState({ sort: value });
  if (selectedId) {
    this.handleAssetsClick(selectedId);
  }
}

// might want to rename this since it may be called without a click
handleAssetsClick(id){
  const {
    assetsarr,
    sort = 'id' // get selected sort, default to 'id'
  } = this.state;

  const clickedassetsdata = assetsarr
    .filter(asset => asset.collectionId === id)
    .sort(sort[sort]); // sort according to state.sort value

  this.setState({
    selectedId: id,
    clickedassets: clickedassetsdata
  });
}


<select name="sorting" onChange={onSortChange}>
  {
    // render select options based on available sort functions
    Object.keys(sort).map(sortOption => (
      <option key={sortOption}>{sortOption}</option>
    ))
  }
</select>

推荐阅读