如何根据下拉值过滤/渲染项目?

时间:2018-08-22 14:34:42

标签: javascript arrays reactjs

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

该数组如下所示:

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(也由状态处理)进行过滤。我目前的处理方式是这样的:

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之类的东西时,在此过滤条件下,我将得到如下结果: enter image description here

enter image description here

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

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

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

1 个答案:

答案 0 :(得分:1)

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

编辑示例

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