【问题标题】:React How to handle checked and unchecked events for checkbox using typescript反应如何使用打字稿处理复选框的选中和未选中事件
【发布时间】:2021-06-03 04:51:53
【问题描述】:

您好,我是 React 和 typescript 的新手。我正在为复选框添加选中的属性,但发现它很棘手。我搜索了 SO,但仍然无法让它更接近工作。

这是我想要做的:

我正在使用单个子组件创建三个复选框组件[此处显示]。它们都有自己的值,我需要动态传递。

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"
          />
);

问题是我不确定如何设置选中的属性,基于点击。当我使用

checked={this.props.checked}

我正在检查所有复选框。或者如果我使用

checked={this.handleClick}

我收到错误提示

不能在 typescript 中将 void 分配给布尔值。

任何有关如何解决此问题的建议都会非常有帮助

提前致谢

【问题讨论】:

    标签: javascript reactjs events checkbox react-redux


    【解决方案1】:

    如果你想快速,在底部添加了在线演示。我几乎重写了所有这些东西。


    一些注意点:

    • 由于您想重用子复选框,因此您不应在子复选框中编写处理函数,而是将其公开给父复选框。
    • onClick - MouseEventonChange - ChangeEvent 都可以,因为它是完全受控的,我们唯一需要传递的是它的 id。检查状态由父母持有。
    • 您可以根据父级传递的道具在子级内部编写嵌套检查逻辑。
    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>
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      其实这里不需要onClick prop,checked prop 只需要布尔值

      根据反应文档,如果您有多个复选框,这应该是正确的方法

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

      【讨论】:

        【解决方案3】:

        错误 1

        您正在为checked 设置函数而不是布尔值。这是错误的。我不知道 TypeScript 是如何让你这样做的

        错误 2

        同时使用onClick()onChange()。不要那样做。只使用一个。更喜欢onChange() 而不是onClick()

        更正的代码

        // Parent Component
        handleClick = (checked: boolean, id: string) => {
          this.setState(prevState => ({ 
            checked: { ...prevState.checked, [id]: checked }
          })) // or however you structured this state
        }
        
        
        // Child component
        // 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"
                  />
        )
        

        【讨论】:

          【解决方案4】:

          你可以使用MCheckbox

          进口:

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

          功能:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-01-21
            • 2021-12-19
            • 2017-04-21
            • 1970-01-01
            • 2018-02-05
            • 2018-12-28
            • 1970-01-01
            相关资源
            最近更新 更多