You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React单选按钮薪资筛选功能失效问题排查求助

React薪资范围单选按钮筛选功能修复

我需要点击单选按钮时,根据按钮文本过滤薪资数组中的职位数据并渲染结果。目前就业类型复选框筛选功能正常,但复用相同逻辑实现薪资范围单选按钮筛选时失效。以下是修正后的完整React组件代码:

import {Component} from 'react'
import Cookies from 'js-cookie'
import {FcSearch} from 'react-icons/fc'
import {IoMdStar} from 'react-icons/io'
import {BsFillBagFill} from 'react-icons/bs'
import {ImLocation2} from 'react-icons/im'
import './index.css'

const employmentTypesList = [
  {
    label: 'Full Time',
    employmentTypeId: 'FULLTIME',
  },
  {
    label: 'Part Time',
    employmentTypeId: 'PARTTIME',
  },
  {
    label: 'Freelance',
    employmentTypeId: 'FREELANCE',
  },
  {
    label: 'Internship',
    employmentTypeId: 'INTERNSHIP',
  },
]

const salaryRangesList = [
  {
    salaryRangeId: '1000000',
    label: '10 LPA and above',
  },
  {
    salaryRangeId: '2000000',
    label: '20 LPA and above',
  },
  {
    salaryRangeId: '3000000',
    label: '30 LPA and above',
  },
  {
    salaryRangeId: '4000000',
    label: '40 LPA and above',
  },
]

class JobsRoute extends Component {
  state = {
    profileList: [],
    jobsList: [],
    searchInput: '',
    EmployList: [],
    SalaryList: '',
  }

  componentDidMount() {
    this.renderProfile()
    this.renderJobsApi()
  }

  searchBox = event => {
    this.setState({searchInput: event.target.value})
  }

  renderProfile = async () => {
    const url = 'https://apis.ccbp.in/profile'
    const jwtToken = Cookies.get('jwt_token')

    const options = {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${jwtToken}`,
      },
    }
    const response = await fetch(url, options)
    if (response.ok === true) {
      const data = await response.json()
      const updatedData = {
        name: data.profile_details.name,
        profileImageUrl: data.profile_details.profile_image_url,
        shortBio: data.profile_details.short_bio,
      }

      this.setState({profileList: updatedData})
    }
  }

  renderProfileList = () => {
    const {profileList} = this.state
    const {name, profileImageUrl, shortBio} = profileList

    return (
      <div className="profile-container">
        <div className="profile">
          <img src={profileImageUrl} alt="profileImage" />
          <h1 style={{color: 'blue'}}>{name}</h1>
          <p style={{color: 'black'}}>{shortBio}</p>
        </div>
      </div>
    )
  }

  renderJobsApi = async () => {
    const {EmployList, SalaryList, searchInput} = this.state
    const JobsUrl = `https://apis.ccbp.in/jobs?employment_type=${EmployList}&package_per_annum=${SalaryList}&search=${searchInput}`
    const jwtJobsToken = Cookies.get('jwt_token')

    const JobOptions = {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${jwtJobsToken} `,
      },
    }
    const response = await fetch(JobsUrl, JobOptions)
    if (response.ok === true) {
      const jobData = await response.json()
      const updatedJobsData = jobData.jobs.map(jobItem => ({
        companyLogoUrl: jobItem.company_logo_url,
        employmentType: jobItem.employment_type,
        id: jobItem.id,
        jobDescription: jobItem.job_description,
        location: jobItem.location,
        packagePerAnnum: jobItem.package_per_annum,
        rating: jobItem.rating,
        title: jobItem.title,
      }))

      this.setState({jobsList: updatedJobsData})
    }
  }

  EmployLists = event => {
    const {EmployList} = this.state
    const CheckboxNotInLists = EmployList.filter(
      each => each === event.target.id,
    )
    if (CheckboxNotInLists.length === 0) {
      this.setState(
        prevState => ({
          EmployList: [...prevState.EmployList, event.target.id],
        }),
        this.renderJobsApi,
      )
    } else {
      const filterData = EmployList.filter(each => each !== event.target.id)
      this.setState(
        {
          EmployList: filterData,
        },
        this.renderJobsApi,
      )
    }
  }

  SalaryLists = event => {
    this.setState({SalaryList: event.target.id}, this.renderJobsApi)
  }

  buttonSearch = () => {
    this.renderJobsApi()
  }

  searchInputDown = event => {
    if (event.key === 'Enter') {
      this.renderJobsApi()
    }
  }

  render() {
    const {jobsList, searchInput} = this.state
    return (
      <div className="job-container">
        <div className="profile-container">
          <div style={{marginLeft: '38px'}}>{this.renderProfileList()}</div>
          <hr style={{marginTop: '25px', marginLeft: '38px'}} />
          <p style={{color: 'white', marginTop: '10px', marginLeft: '38px'}}>
            Type of Employment
          </p>
          <ul className="unordered">
            {employmentTypesList.map(each => (
              <li key={each.employmentTypeId} className="listed">
                <input
                  onChange={this.EmployLists}
                  value={each.label}
                  type="checkbox"
                  className="checkbox"
                  id={each.employmentTypeId}
                />
                <label className="label-name" htmlFor={each.employmentTypeId}>
                  {each.label}
                </label>{' '}
              </li>
            ))}
          </ul>
          <hr style={{marginTop: '25px', marginLeft: '38px'}} />
          <p style={{color: 'white', marginTop: '10px', marginLeft: '38px'}}>
            Salary Range
          </p>
          <ul className="unordered">
            {salaryRangesList.map(each => (
              <li key={each.salaryRangeId} className="listed">
                <input
                  type="radio"
                  name="salaryRange"
                  value={each.label}
                  onChange={this.SalaryLists}
                  id={each.salaryRangeId}
                />
                <label className="label-name" htmlFor={each.salaryRangeId}>
                  {each.label}
                </label>
              </li>
            ))}
          </ul>
        </div>
        <div className="search-container">
          <div className="search-box">
            <input
              type="search"
              className="search-bar"
              placeholder="Search"
              value={searchInput}
              onChange={this.searchBox}
              onKeyDown={this.searchInputDown}
            />
            <button
              className="search"
              onClick={this.buttonSearch}
              type="button"
              data-testid="searchButton"
              aria-label="Search"
            >
              <FcSearch className="search-icon" />
            </button>
          </div>
          <ul>
            {jobsList.map(jobItem => (
              <li className="list-jobdetails" key={jobItem.id}>
                <div className="container">
                  <img
                    src={jobItem.companyLogoUrl}
                    alt="job details company logo"
                    className="job-image"
                  />
                  <div className="title-rating">
                    <h1>{jobItem.title}</h1>
                    <div className="star-rating">
                      <IoMdStar className="star" />
                      <p>{jobItem.rating}</p>
                    </div>
                  </div>
                </div>

                <div className="location-employment">
                  <div className="loc-emp">
                    <ImLocation2 />
                    <p style={{marginLeft: '8px'}}>{jobItem.location}</p>

                    <BsFillBagFill style={{marginLeft: '13px'}} />
                    <p style={{marginLeft: '8px'}}>{jobItem.employmentType}</p>
                  </div>
                  <p>{jobItem.packagePerAnnum}</p>
                </div>
                <hr />
                <h2 style={{marginTop: '10px'}}>Description</h2>
                <p style={{marginTop: '10px'}}>{jobItem.jobDescription}</p>
              </li>
            ))}
          </ul>
        </div>
      </div>
    )
  }
}
export default JobsRoute

关键修复说明

  • 薪资单选按钮事件处理函数SalaryLists直接将选中项的id(对应薪资范围数值)存入状态SalaryList,并在状态更新后立即触发API请求重新拉取数据
  • API请求URL中正确传递package_per_annum参数,确保后端能根据选中的薪资范围筛选职位
  • 所有薪资单选按钮设置相同的name="salaryRange",保证同一时间仅能选中一个选项

内容的提问来源于stack exchange,提问作者Satish Medapalli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:04:51