反应三态复选框不确定空错误

React tri-state checkbox indeterminate null error

我正在尝试实现一个三态复选框来做出反应。重复单击复选框会像这样在 blank->checked->crossed->blank->... 中循环。环顾四周并寻找答案,我找到了一个参考:.

我试过这样的事情:

export default function App() {
  const [state, setState] = React.useState({
    data: [
      {
        id: "1",
        one: 0
      },
      {
        id: "2",
        one: 0
      }
    ]
  });
  const indetSetter = React.useCallback(
    (el, id) => {

      if (el) {
        if (el.id === id && state.data.map((datum) => datum.one === 2)) {
          el.indeterminate = true;
        }
      }
    },
    [state]
  );

  const advance = (id, e) => {
    setState((state) => {
      
      state.data.map((datum) =>
        datum.id === id ? { ...datum, one: (datum.one + 1) % 3 } : { ...datum }
      );
    });

  return (
    <>
      {state.data.map((item) => {
        // console.log("show", item);
        return (
          <input
            key={item.id}
            id={item.id}
            type="checkbox"
            checked={item.one === 1}
            ref={(el) => indetSetter(el, item.id)}
            onChange={(e) => advance(item.id, e)}
          />
        );
      })}
    </>
  );
}

但最终它抛出一个错误:can't access property "indeterminate", el is nullcan't access property "data", state is undefined

工作片段:https://codesandbox.io/s/relaxed-hill-qqb4y

非常感谢任何解决此问题的帮助。

提前致谢:)

正如我评论的那样,您需要将不确定的逻辑封装在一个单独的组件中,以便能够在值通过 useEffect 更改时更新 dom,如 here[=16 所述=]

这是单个不确定复选框的组件

IndeterminateInput.js

import React, { useCallback, useEffect, useRef } from 'react';

export default function IndeterminateInput({ id, name, value, onChange }) {
  const el = useRef(null);

  const onChangeHandler = useCallback(
    event => {
      onChange({ id, name, value: (value + 1) % 3 });
    },
    [id, name, value, onChange],
  );

  useEffect(() => {
    el.current.checked = value === 1;
    el.current.indeterminate = value === 2;
  }, [value]);

  return (
    <input type="checkbox" name={name} ref={el} onChange={onChangeHandler} />
  );
}

然后通过必要的 props

为主要组件中的每个项目渲染一个 IndeterminateInput
export default function App() {
  const [state, setState] = ...

  const onChange = useCallback((item) => {
    const { id, value } = item;
    setState((prevState) => {
      return {
        data: prevState.data.map((datum) => {
          return id === datum.id
            ? {
                ...datum,
                one: value
              }
            : datum;
        })
      };
    });
  }, []);

  return (
    <>
      {state.data.map((item, i) => {
        return (
          <IndeterminateInput
            key={item.id}
            id={item.id}
            name={item.name}
            value={item.one}
            onChange={onChange}
          />
        );
      })}
    </>
  );
}

你可以看到它在这里工作:https://codesandbox.io/s/stoic-euler-e97so?file=/src/App.js