reactjs React复选框组件需要单击两次才能更改为选中状态

bbuxkriu  于 2022-12-12  发布在  React
关注(0)|答案(3)|浏览(269)

我有一个呈现复选框的React组件。问题是它需要两次点击才能变成选中,然后两次点击才能变成未选中。
JS:

import React, { Component } from "react";

class CheckboxRow extends Component {
  constructor(props) {
    super(props);
    this.state = { checked: false };
  }

  inputChangedHandler() {
    this.setState({ checked: !this.state.checked });
  }

  render() {
    return (
      <div className="checkbox-row">
        <input
          id={this.props.id}
          type="checkbox"
          onChange={() => this.inputChangedHandler()}
          checked={this.state.checked}
        />
        <label htmlFor={this.props.id} className="checkbox-row__label">
          Label goes here
        </label>
      </div>
    );
  }
}

export default CheckboxRow;

那么,我需要做些什么,使复选框变成选中一次点击,并改变回未选中一次点击?

xkftehaa

xkftehaa1#

在盯着它看了几个小时后,我突然有了一个Eureka 时刻!我有一个prevent.default()的形式onChange!删除prevent.default()修复了它,感谢那些已经回复的人。

xuo3flqw

xuo3flqw2#

更改状态时,不应直接访问旧状态,例如

this.setState({ checked: !this.state.checked });

而是做了

this.setState(({ checked }) => ({ checked: !checked }));

或者从onChange访问传递的事件。

function CheckboxRow({ id }) {
  const [checked, setChecked] = useState(false);

  const onChange = event => {
    event.persist();
    setChecked(event.target.checked);
  };

  return (
    <div className="checkbox-row">
      <input id={id} type="checkbox" onChange={onChange} checked={checked} />
      <label htmlFor={id} className="checkbox-row__label">
        Label goes here
      </label>
    </div>
  );
}
ubof19bj

ubof19bj3#

由于我也面临同样的问题,我继续前面的讨论,但是删除prevent.default并不会改变任何事情:
基本上,我使用react hook表单来进行高级过滤和倍数选择:
即使在第一次单击时捕获onChange事件,“checkbox”输入也需要两次单击才能真正选中:

import classes from "./JobsFiltering.module.css";
import {
  useEffect,
  useState
} from "react";

import Link from "next/link";
import Image from "next/image";
import React from "react";
// import Pagination from "../Pagination";

import SearchIcon from "@mui/icons-material/Search";

import JobsList from "./JobsList";

import {
  useForm,
  Controller
} from "react-hook-form";
import {
  TextField,
  Checkbox
} from "@mui/material";
import MuiAutoComplete from "./LimitTags";
import SliderSalary from "./SliderSalary";
import CheckBoxWorkTypes from "./CheckBoxWorkTypes";

export default function JobsFiltersBox(props) {
  // const { jobs } = props;
  const [jobs, setJobs] = useState([]);

  // REACT HOOK FORM SET UP
  const defaultValues = {
    select: "",
    input: "",
    mode: "onChange",
    reValidateMode: "onChange",
  };

  const {
    register,
    handleSubmit,
    control,
    formState: {
      errors
    },
  } = useForm({
    defaultValues,
  });

  // SEARCH JOBS ASYNC FUNCTION API CALL
  async function searchJobs(formProperties = {}) {
    return fetch("/api/jobs/queries", {
        method: "POST",
        body: JSON.stringify(formProperties),
        headers: {
          "Content-Type": "application/json",
        },
      })
      .then((response) => response.json())
      .then((json) => setJobs(json))
      .catch((error) => console.log(error));
  }

  // LISTEN TO FILTERS
  async function onChange(data, event) {
    // event.preventDefault();
    console.log(data);

    searchJobs({
      experienceLevels: data.seniority,
      remoteTypes: data.remoteTypes,
      workTypes: data.workTypes,
      tags: data.tags,
      terms: data.terms,
      salaryRanges: data.salaryRanges,
      sortBy: data.sortBy,
    });
  }

  // ALLOW A CALL TO SEARCH JOB WHEN COMPONENT DID MOUN - AT INITIALIZATION
  useEffect(() => {
    searchJobs();
  }, []);

  //  ****

  // FIEDS OPTIONS DEFINITION
  const seniorities = ["Junior", "Intermediate", "Senior"];
  const remoteTypes = ["Full Remote", "Hybrid", "No Remote"];
  const workTypes = [
    "Full-time",
    "Part-time",
    "Internship",
    "Contractor",
    "Cofounder",
  ];

  return ( <
    section className = {
      classes["section-jobs-filter"]
    } >
    <
    div className = {
      classes["global-box"]
    } > { /* LEFT SIDE */ } { /* LEFT SIDE TO BE PUT HERE WHEN READY */ } <
    div className = {
      classes["sidebar-box"]
    } >
    <
    form onChange = {
      handleSubmit(onChange)
    }
    className = {
      classes["sidebar-form"]
    } >
    { /* SEARCH BAR */ } <
    div className = {
      classes["filter-card"]
    } >
    <
    label className = {
      classes.label
    }
    htmlFor = "filter" >
    Filters <
    /label> <
    input type = "search"
    placeholder = "Search.."
    className = {
      classes["input-main-filters"]
    } { ...register("terms", {})
    }
    /> <
    /div>

    { /* Seniority Level */ } <
    div className = {
      classes["box-category"]
    } >
    <
    div className = {
      classes.row
    } >
    <
    h4 className = {
      classes.label
    } > Seniority < /h4> <
    /div> <
    div className = {
      classes["filter-list"]
    } > {
      seniorities.map((optionName, i) => ( <
        React.Fragment key = {
          optionName
        } >
        <
        label key = {
          optionName
        }
        className = {
          classes.filter
        } >
        <
        input type = "checkbox"
        value = {
          optionName
        }
        name = "seniority" { ...register("seniority", {})
        }
        // className={
        //   data.seniority.include({ optionName })
        //     ? "activated"
        //     : "toggledButtonId"
        // }
        /> {
          optionName
        } <
        /label> <
        /React.Fragment>
      ))
    } <
    /div> <
    /div>

    { /* remoteType */ } <
    div className = {
      classes["box-category"]
    } >
    <
    div className = {
      classes.row
    } >
    <
    h4 className = {
      classes.label
    } > Remote Work < /h4> <
    /div> <
    div className = {
      classes["filter-list"]
    } > {
      remoteTypes.map((c, i) => ( <
        React.Fragment key = {
          c
        } >
        <
        label key = {
          c
        }
        className = {
          classes.filter
        } >
        <
        input type = "checkbox"
        value = {
          c
        }
        name = "remoteTypes" { ...register("remoteTypes", {})
        }
        /> {
          c
        } <
        /label> <
        /React.Fragment>
      ))
    } <
    /div> <
    /div>

    { /* workType */ } <
    div className = {
      classes["box-category"]
    } >
    <
    div className = {
      classes.row
    } >
    <
    h4 className = {
      classes.label
    } > Work Type < /h4> <
    /div> <
    div className = {
      classes["filter-list"]
    } > {
      workTypes.map((workTypeName, i) => ( <
        React.Fragment key = {
          workTypeName
        } >
        <
        label key = {
          workTypeName
        }
        className = {
          classes.filter
        } >
        <
        input type = "checkbox"
        value = {
          workTypeName
        }
        name = "workTypes" { ...register("workTypes", {})
        }
        /> {
          workTypeName
        } <
        /label> <
        /React.Fragment>
      ))
    } <
    /div> <
    /div>

    { /* <CheckBoxWorkTypes control={control} /> */ }

    { /* Compensation range */ } { /* Not operational yet */ } <
    SliderSalary control = {
      control
    }
    /> { /* Location : city or country ? */ } { /* <CountrySelect control={control} /> */ } { /* Tags - with "voir plus" options ? */ } <
    div className = {
      classes["filter-list"]
    } >
    <
    MuiAutoComplete control = {
      control
    }
    /> <
    /div> <
    /form> <
    /div>

    { /* RIGHT SIDE */ } <
    div className = {
      classes["jobs-list-box"]
    } >
    <
    div className = {
      classes["sort-by"]
    } >
    <
    form onChange = {
      handleSubmit(onChange)
    } >
    <
    div className = {
      classes["select-wrapper"]
    } >
    <
    span > Sort by: < /span> <
    select { ...register("sortBy")
    }
    className = {
      classes["sort-by--select"]
    }
    id = "select" >
    <
    option value = "date" > Date < /option>
    `` <
    option value = "compensation" > Compensation < /option> { /* Later on: most view, hottest, etc.. */ } <
    /select> <
    /div> <
    /form>

    { /*  */ } <
    /div>

    <
    div className = {
      classes["jobs-list"]
    } >
    <
    div className = {
      classes["jobs-list"]
    } >
    <
    JobsList jobs = {
      jobs
    }
    /> <
    /div> <
    /div> {
      /* <div className={classes["box-pagination"]}>
                  <Pagination />
                </div> */
    } <
    /div> <
    /div> <
    /section>
  );
}

参见第120行的示例:https://codepen.io/Marving972/pen/PoagGNP?editors=0010

相关问题