最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React How to handle checked and unchecked events for checkbox using typescript - Stack Overflow

programmeradmin1浏览0评论

Hi I am new to React and typescript. I am working on adding checked attribute for a checkbox but find it tricky. I searched across SO but still couldn't get it closer to working.

Here is what I am trying to do:

I am creating three checkbox ponents using a single child ponent[shown here]. They all have their own values that I need to pass dynamically.

interface ItemProps {
  readonly className?: string;
  readonly checked: boolean | undefined;
  readonly accentedUnchecked?: boolean;
  readonly imageUrl: string;
  readonly errorMessage?: string;
  readonly statusChecked?: boolean | undefined;
  readonly onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
  readonly handleClick: (event: React.ChangeEvent<HTMLInputElement>) => void; 
  };

  readonly hasError?: boolean;
  readonly title?: string;
  readonly value?: number;
  readonly description?: React.ComponentType;
}
export class Item extends React.Component<
  ItemProps,
  {
    readonly isExpanded: boolean;
    readonly checkboxStatus: boolean;
    readonly temp: boolean;
    readonly checked: boolean;    
  }
> {
  constructor(props) {
    super(props);
    this.state = {
      isExpanded: false,
      checkboxStatus: false,
      temp: false,
      checked: this.state.temp
    };
    this.handleClick = this.handleClick.bind(this);
    this.onChange = this.onChange.bind(this);    
  }`

  private onChange(e: React.ChangeEvent<HTMLInputElement>) {   
    this.setState({ temp: e.currentTarget.checked });
  }

  private readonly handleClick = e =>
    this.props.onChange({
      currentTarget: { checked: e.currentTarget.checked }
    } as any);

  render() {

    const unchecked = this.props.accentedUnchecked && this.props.checked === false;

    return (

<label className="checkbox">
          <input
            type="checkbox"
            checked={this.onChange} //Not working
            onChange={this.props.onChange}
            onClick={this.handleClick}

            id={"test"}
            data-id="0"
          />
);

The problem is I am not sure how to set the checked attribute, based onClick. when I use

checked={this.props.checked}

I am getting all checkboxes checked. Or if I use

checked={this.handleClick}

I get error saying

cannot assign void to a boolean" in typescript.

Any suggestion on how this can be resolved will be very helpful

Thanks in advance

Hi I am new to React and typescript. I am working on adding checked attribute for a checkbox but find it tricky. I searched across SO but still couldn't get it closer to working.

Here is what I am trying to do:

I am creating three checkbox ponents using a single child ponent[shown here]. They all have their own values that I need to pass dynamically.

interface ItemProps {
  readonly className?: string;
  readonly checked: boolean | undefined;
  readonly accentedUnchecked?: boolean;
  readonly imageUrl: string;
  readonly errorMessage?: string;
  readonly statusChecked?: boolean | undefined;
  readonly onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
  readonly handleClick: (event: React.ChangeEvent<HTMLInputElement>) => void; 
  };

  readonly hasError?: boolean;
  readonly title?: string;
  readonly value?: number;
  readonly description?: React.ComponentType;
}
export class Item extends React.Component<
  ItemProps,
  {
    readonly isExpanded: boolean;
    readonly checkboxStatus: boolean;
    readonly temp: boolean;
    readonly checked: boolean;    
  }
> {
  constructor(props) {
    super(props);
    this.state = {
      isExpanded: false,
      checkboxStatus: false,
      temp: false,
      checked: this.state.temp
    };
    this.handleClick = this.handleClick.bind(this);
    this.onChange = this.onChange.bind(this);    
  }`

  private onChange(e: React.ChangeEvent<HTMLInputElement>) {   
    this.setState({ temp: e.currentTarget.checked });
  }

  private readonly handleClick = e =>
    this.props.onChange({
      currentTarget: { checked: e.currentTarget.checked }
    } as any);

  render() {

    const unchecked = this.props.accentedUnchecked && this.props.checked === false;

    return (

<label className="checkbox">
          <input
            type="checkbox"
            checked={this.onChange} //Not working
            onChange={this.props.onChange}
            onClick={this.handleClick}

            id={"test"}
            data-id="0"
          />
);

The problem is I am not sure how to set the checked attribute, based onClick. when I use

checked={this.props.checked}

I am getting all checkboxes checked. Or if I use

checked={this.handleClick}

I get error saying

cannot assign void to a boolean" in typescript.

Any suggestion on how this can be resolved will be very helpful

Thanks in advance

Share Improve this question edited Mar 23, 2020 at 10:48 Regokonda asked Mar 23, 2020 at 9:14 RegokondaRegokonda 971 gold badge2 silver badges11 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 3

If you want to be quick, online demo has been added at the bottom. I rewrite almost all those stuff.


Some notice points:

  • Since you want to reuse the child checkbox, you shouldn't write the handler functions inside the child, expose then to parents instead.
  • Both onClick - MouseEvent and onChange - ChangeEvent would be fine since it's fully controlled, the only thing we need to pass is its id. The checked status is held by the parents.
  • You can write nested checked logic inside the child, based on the props passed from parents.
import * as React from "react";
import "./styles.css";

const data = [
  { id: 1, checked: 1 },
  { id: 2, checked: 0 },
  { id: 3, checked: 1 }
];

export default function App() {
  const [checkedList, setCheckedList] = React.useState(
    data.map(x => !!x.checked)
  );
  const onChangeHandler = (
    e: React.ChangeEvent<HTMLInputElement>,
    id: number
  ) => {
    const list = [...checkedList];
    list.splice(id - 1, 1, !list[id - 1]);
    setCheckedList(list);
  };
  return (
    <div className="App">
      <h1>Checkboxes</h1>
      {data.map((item, idx) => (
        <InsuranceItem
          id={item.id}
          key={item.id}
          checked={checkedList[idx]}
          onChange={onChangeHandler}
        />
      ))}
    </div>
  );
}

interface InsuranceItemProps {
  readonly id?: number;
  readonly className?: string;
  readonly checked: boolean | undefined;
  readonly accentedUnchecked?: boolean;
  readonly imageUrl?: string;
  readonly errorMessage?: string;
  readonly statusChecked?: boolean | undefined;
  readonly onChange: (
    event: React.ChangeEvent<HTMLInputElement>,
    id: number
  ) => void;
  // readonly handleClick: (event: React.ChangeEvent<HTMLInputElement>) => void;
  readonly hasError?: boolean;
  readonly title?: string;
  readonly value?: number;
  readonly description?: React.ComponentType;
}
class InsuranceItem extends React.Component<
  InsuranceItemProps,
  {
    // readonly isExpanded: boolean;
    // readonly checkboxStatus: boolean;
    // readonly temp: boolean;
    // readonly checked: boolean;
  }
> {
  constructor(props: InsuranceItemProps) {
    super(props);
    this.state = {
      // isExpanded: false,
      // checkboxStatus: false,
      // checked: false
    };
  }

  render() {
    const { id = 0, accentedUnchecked, checked, onChange } = this.props;
    // const unchecked = accentedUnchecked && checked === false;

    return (
      <label className="checkbox">
        <input
          type="checkbox"
          checked={checked}
          onChange={e => onChange(e, id)}
          id={id.toString()}
          data-id="0"
        />
      </label>
    );
  }
}

Actually you will not needed onClick prop here, and checked prop is only expect boolean value

As per react docs, this should be the right way if you have multiple check boxes

 handleInputChange(event) {
        const target = event.target;
        const value = target.name === 'isGoing' ? target.checked : target.value;
        const name = target.name;

        this.setState({
          [name]: value
        });
      }

    <input
       name="isGoing"
       type="checkbox"
       checked={this.state.isGoing}
       onChange={this.handleInputChange} />

Mistake 1

You're setting function instead of boolean for checked. Which is wrong. I don't know how TypeScript is allowing you to do that

Mistake 2

Using onClick() and onChange() together. Don't do that. Use only one. Prefer onChange() to onClick() here.

Corrected code

// Parent Component
handleClick = (checked: boolean, id: string) => {
  this.setState(prevState => ({ 
    checked: { ...prevState.checked, [id]: checked }
  })) // or however you structured this state
}


// Child ponent
// Creating ID as variable 
const id = 'test';

handleClick = ev => {
  // Avoid passing `ev` directly
  this.props.handleClick(ev.currentTarget.value, id)
}

return (
          <input
            type="checkbox"
            checked={this.props.checked}
            onChange={this.handleClick}
            id={id}
            data-id="0"
          />
)

you can use MCheckbox

import :

import { MCheckbox } from '../@material-extend';

function :

    function handleLike(e) {

    if (e.target.checked) {
    // your code here when it checked
    } else {
     //your code here when it is not checked
    } 
  }

jsx :

          <MCheckbox
            onChange={(e) => handleLike(e)}
            defaultChecked={false}
            size="small"
            color="error"
            icon={<Icon icon={heartFill} />}
            checkedIcon={<Icon icon={heartFill} />}
          />
发布评论

评论列表(0)

  1. 暂无评论