首页 > 解决方案 > 如何根据下拉值过滤/渲染项目?

问题描述

我有一个对象数组,我想从中过滤出一些项目并根据具有值的下拉列表在视图中呈现它(这也由状态管理)。

数组如下所示:

const arr = [
  {
    departmentName: 'Operations',
    jobs: [
      {
        url: 'https:...',
        description: '....',
        department: 'Operations'
        location: 'New York, NY'
      }
    ],
  },
  {
    departmentName: 'Brand Marketing',
    jobs: [
      {
        url: 'https:...',
        description: '....',
        department: 'Brand Marketing'
        location: 'New York, NY'
      }
    ],
  },
  {
    departmentName: 'Brand Marketing',
    jobs: [
      {
        url: 'https:...',
        description: '....',
        department: 'Brand Marketing'
        location: 'Austin, TX'
      }
    ],
  },
  ....
];

到目前为止,在我看来,我能够渲染所有数据:

type DepartmentJob = {
  departmentName: string;
  jobs: Job[];
};

export type Job = {
  applyUrl: string;
  department: string;
  description: string;
  id: string;
  location: string;
  order: any;
  title: string;
};


class View extends React.Component<Props, State> {
  public constructor(props: Props) {
    super(props);
    this.state = {
      selectedLocation: 'All Locations'
    }
  }

  public render() {
    const { locations, careers } = this.props;
    const { selectedLocation } = this.state;

      return (
        <Container>
          <Select
            label={selectedLocation}
            options={locations}
            onChange={(e: React.FormEvent<HTMLSelectElement>) => this.handleChange(e.currentTarget.value)}
            value={selectedLocation}
          />
          {careers.map((career: DepartmentJob) =>
            <DepartmentContainer key={career.departmentName}>
              <DepartmentName>{career.departmentName}</DepartmentName>
              <JobsContainer>
                {career.jobs.map(({ title, id, location }: Job) =>
                  <Card
                    key={id}
                    id={id}
                    title={title}
                    location={location}
                  />,
                )}
              </JobsContainer>
            </DepartmentContainer>,
          )}
        </Container>
      )
    }

  private handleChange = (selectedLocation: string) =>
    this.setState({ selectedLocation });
}

所以现在我想根据Select, 或 Dropdown 过滤这些,这也是由 state 处理的。我正在处理的当前方式是这样的:

public render() {
    const { locations, careers } = this.props;
    const { selectedLocation } = this.state;
      if (this.state.selectedLocation !== 'All Locations') {

      return ( 
        <Container>
          <Select
            label={selectedLocation}
            options={locations}
            onChange={(e: React.FormEvent<HTMLSelectElement>) => this.handleChange(e.currentTarget.value)}
            value={selectedLocation}
          />
          {careers.filter((career: DepartmentJob) =>
            career.jobs.some((job: Job) => job.location === selectedLocation)
          ).map((filteredJob: DepartmentJob) =>
            <DepartmentContainer key={filteredJob.departmentName}>
              <DepartmentName>{filteredJob.departmentName}</DepartmentName>
              <JobsContainer>
                {filteredJob.jobs.map(({ title, id, location }: Job) =>
                  <Card
                    key={id}
                    id={id}
                    title={title}
                    location={location}
                  />,
                )}
              </JobsContainer>
            </DepartmentContainer>,
          )}
        </Container>
      )
    }

但是,这会产生我不想要的结果。当我Austin, TX在此过滤中选择类似 的内容时,我会得到如下结果: 在此处输入图像描述

或者

在此处输入图像描述

我不确定为什么我得到的结果好坏参半。我假设问题出在我过滤的方式上:

jobs.filter((job: DepartmentJob) =>
                job.jobs.some((job: Job) => job.location === selectedLocation)
              ).map((filteredJob: DepartmentJob => filteredJob)

我的问题是:如何返回与我作为选定值完全匹配的所有位置?

标签: javascriptarraysreactjs

解决方案


问题在于,如果所有元素之一满足条件some,它将返回。true因此,如果与下拉值匹配,集合中的内容无关紧要,它将返回true

编辑示例

jobs.reduce( (acc, current) => acc.concat(current.filter( job => job.location === selectedLocation)))

推荐阅读