简体   繁体   中英

How to filter/render items based on dropdown value?

I have an array of objects and I want to filter some items out of it and render it in the view based on a dropdown that has a value (which is also managed by state).

The array looks like this:

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'
      }
    ],
  },
  ....
];

So far, in my view, I'm able to render all of data:

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 });
}

So now I want to filter these based on the Select , or Dropdown, which is also handled by state. The current way I'm handling this is like this:

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>
      )
    }

However this produces results that I don't want. When I select something like Austin, TX , within this filtering, I'll get some results like so: 在此处输入图片说明

or

在此处输入图片说明

I'm not sure why I'm getting mixed results. I'm assuming the problem lies here in the way I'm filtering:

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

My question is: how do I return all the locations that match exactly what I have as the selected value?

The problem is with some , it will return true if one of all elements satisfies the condition. So it doesn´t matter what is in the collection if one matches the dropdown value, it will return true .

EDIT EXAMPLE

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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