反应三态复选框不确定空错误
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 null
或 can'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
我正在尝试实现一个三态复选框来做出反应。重复单击复选框会像这样在 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 null
或 can'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