代码之家  ›  专栏  ›  技术社区  ›  Leonel Galán

在父组件和子组件中保持状态(复选框和复选框)

  •  0
  • Leonel Galán  · 技术社区  · 6 年前

    我写道 复选框 组件,该组件接收初始“已选中”,并保持复选框是否处于选中状态。它通过一个 onChange 道具

    我有一个 复选框 渲染多个对象的组件 复选框 组件,它接受选项列表以及应该选中哪些选项,但该组件也会跟踪其状态中选中的复选框。

    看来这让 复选框 它自己的状态已经过时,因为当 复选框 根据其状态重新渲染。 一切都很有效 ,但对我来说,这感觉像是一种代码气味。

    问题:

    1. 我应该在乎吗 复选框 中国的状态不再相关了?我可以编写这个组件,仅基于它的道具进行渲染,但我可能会在其他地方使用这个组件,而不是在 复选框 .
    2. 我是否缺少一种模式或最佳实践?
    3. 有人看到这里也有代码气味吗?
    const { useState, Fragment } = React;
    const { render } = ReactDOM;
    
    const Checkbox = ({
      label,
      value,
      checked: initialChecked,
      onChange,
    }) => {
      const [isChecked, setIsChecked] = useState(initialChecked);
    
      const handleChange = ({ target: { value, checked } }) => {
        setIsChecked(checked);
        onChange({ value, checked });
      };
    
      const id = `${name}_${value}`;
    
      return (
        <Fragment>
          <input
            type="checkbox"
            id={id}
            name={name}
            value={value}
            checked={isChecked}
            onChange={handleChange} />
          <label htmlFor={id}>{ label }</label>
        </Fragment>
      );
    };
    
    
    const Checkboxes = ({
      options,
      checked: initialChecked,
    }) => {
      const [values, setValues] = useState(initialChecked);
      const handleChange = ({ value, checked }) => {
        if (checked && !values.includes(value)) {
          setValues([...values, value]);
        } else if (!checked && values.includes(value)) {
          setValues([...values.filter((v) => v !== value)]);
        }
      };
    
      return (
        <Fragment>
          {options.map((option) => (
            <Checkbox
              {...option}
              checked={values.includes(option.value)}
              onChange={handleChange} />
          ))}
        </Fragment>
      );
    }
    
    
    document.addEventListener('DOMContentLoaded', () => {
      render(
        <Checkboxes
          options={[
            { label: 'Foo', name: 'selection', value: 'foo'},
            { label: 'Bar', name: 'selection', value: 'bar' }
          ]}
          checked={['bar']} />,
        document.getElementById('root'),
      );
    });
    

    代码笔上的代码相同: https://codepen.io/leonelgalan/pen/wvBYrOz?editors=0010

    谢谢大家的帮助!

    0 回复  |  直到 6 年前