调用 onClick 事件时,React 状态始终未定义
React state is always undefined when invoke onClick event
所以我有以下代码:
export default function Component() {
const [list, setList] = useState<JSX.Element[]>();
const [active, setActive] = useState<JSX.Element>();
useEffect(()=>{
let startTab = <li key={"0000-0000-0000-0000"} onClick={() => onClick()}>Star 1</li>;
let secondTab = <li key={"0001-0000-0000-0000"} onClick={() => onClick()}>Star 2</li>;
setList(() => [startTab, secondTab]);
setActive(() => startTab);
},[])
const onClick= () =>{
console.log(list)
}
return (
<div id="BodyMain" className={css["Body-container"]}>
<div className={css["tab-header"]}>
{ (
<ul className={css["navs"]}>
{list?.map(tabItem => tabItem)}
</ul>)
}
</div>
<div className={css["tab-body"]}>{}</div>
</div>
);
}
每次我调用 onClick 函数时它只是 returns 未定义!
然而,'React Developer Tools'表明这些状态确实具有价值!!
我无法更改 onClick 函数的状态,因为它始终未定义。我做错了什么?我该如何解决?
问题在于您使用 useEffect() 挂钩的方式。
当您没有任何依赖项时,该钩子将 运行 一次。因此 setList(() => [startTab, secondTab]);只需 运行 一次
如果想每次点击都更新,可以为useEffect() hook添加依赖:
const [list, setList] = useState<JSX.Element[]>();
const [active, setActive] = useState<JSX.Element>();
const [ count, setCount ] = useState (0);
useEffect(()=>{
let startTab = <li key={"0000-0000-0000-0000"} onClick={() => onClick()}>Star 1</li>;
let secondTab = <li key={"0001-0000-0000-0000"} onClick={() => onClick()}>Star 2</li>;
setList(() => [startTab, secondTab]);
setActive(() => startTab);
},[count])
const onClick= () =>{
setCount(() => count+1)
console.log(list)
}
我通常使用计数变量来捕获任何变化并将其设置为 useEffect 依赖项。
阅读更多内容
发生这种情况是因为在第一次渲染期间 list
未定义。并且 useEffect
捕获列表未定义的 onClick
函数。由于 useEffect 运行s 仅一次 - onClick 内的列表将始终未定义。但是如果useEffect会运行,
list 也会在 useEffect 中更新。正如@nam-h-nguyen所说,真正将count
作为依赖项useEffect将重新运行,因此将捕获列表的新值。
实际上,还有另一种解决方案
const [list, setList] = useState<JSX.Element[]>();
const [active, setActive] = useState<JSX.Element>();
const [ count, setCount ] = useState (0);
let startTab = <li key={"0000-0000-0000-0000"} onClick={() =>
onClick()}>Star 1</li>;
let secondTab = <li key={"0001-0000-0000-0000"} onClick={() =>
onClick()}>Star 2</li>;
useEffect(()=>{
setList(() => [startTab, secondTab]);
setActive(() => startTab);
},[])
const onClick= () =>{
setList(() => [startTab, secondTab]);
console.log(list)
}
我所做的是:
- 我从 useEffect() 挂钩中取出了 startTab 和 seconTab,并将它们作为该组件的全局变量,以便我可以在该组件内的任何地方使用它们。
- 然后,我只需要直接在 onClick() 函数中更新“列表”。
- 并且我在第一次渲染期间使用了没有依赖项的 useEffect 来更新列表。
比起把所有东西都放在 useEffect hook() 中,我更喜欢这样做,因为你放在里面的任何东西都会成为它的局部变量,你不能在 useEffect() 钩子之外使用它。
所以我有以下代码:
export default function Component() {
const [list, setList] = useState<JSX.Element[]>();
const [active, setActive] = useState<JSX.Element>();
useEffect(()=>{
let startTab = <li key={"0000-0000-0000-0000"} onClick={() => onClick()}>Star 1</li>;
let secondTab = <li key={"0001-0000-0000-0000"} onClick={() => onClick()}>Star 2</li>;
setList(() => [startTab, secondTab]);
setActive(() => startTab);
},[])
const onClick= () =>{
console.log(list)
}
return (
<div id="BodyMain" className={css["Body-container"]}>
<div className={css["tab-header"]}>
{ (
<ul className={css["navs"]}>
{list?.map(tabItem => tabItem)}
</ul>)
}
</div>
<div className={css["tab-body"]}>{}</div>
</div>
);
}
每次我调用 onClick 函数时它只是 returns 未定义!
然而,'React Developer Tools'表明这些状态确实具有价值!!
我无法更改 onClick 函数的状态,因为它始终未定义。我做错了什么?我该如何解决?
问题在于您使用 useEffect() 挂钩的方式。 当您没有任何依赖项时,该钩子将 运行 一次。因此 setList(() => [startTab, secondTab]);只需 运行 一次
如果想每次点击都更新,可以为useEffect() hook添加依赖:
const [list, setList] = useState<JSX.Element[]>();
const [active, setActive] = useState<JSX.Element>();
const [ count, setCount ] = useState (0);
useEffect(()=>{
let startTab = <li key={"0000-0000-0000-0000"} onClick={() => onClick()}>Star 1</li>;
let secondTab = <li key={"0001-0000-0000-0000"} onClick={() => onClick()}>Star 2</li>;
setList(() => [startTab, secondTab]);
setActive(() => startTab);
},[count])
const onClick= () =>{
setCount(() => count+1)
console.log(list)
}
我通常使用计数变量来捕获任何变化并将其设置为 useEffect 依赖项。
阅读更多内容发生这种情况是因为在第一次渲染期间 list
未定义。并且 useEffect
捕获列表未定义的 onClick
函数。由于 useEffect 运行s 仅一次 - onClick 内的列表将始终未定义。但是如果useEffect会运行,
list 也会在 useEffect 中更新。正如@nam-h-nguyen所说,真正将count
作为依赖项useEffect将重新运行,因此将捕获列表的新值。
实际上,还有另一种解决方案
const [list, setList] = useState<JSX.Element[]>();
const [active, setActive] = useState<JSX.Element>();
const [ count, setCount ] = useState (0);
let startTab = <li key={"0000-0000-0000-0000"} onClick={() =>
onClick()}>Star 1</li>;
let secondTab = <li key={"0001-0000-0000-0000"} onClick={() =>
onClick()}>Star 2</li>;
useEffect(()=>{
setList(() => [startTab, secondTab]);
setActive(() => startTab);
},[])
const onClick= () =>{
setList(() => [startTab, secondTab]);
console.log(list)
}
我所做的是:
- 我从 useEffect() 挂钩中取出了 startTab 和 seconTab,并将它们作为该组件的全局变量,以便我可以在该组件内的任何地方使用它们。
- 然后,我只需要直接在 onClick() 函数中更新“列表”。
- 并且我在第一次渲染期间使用了没有依赖项的 useEffect 来更新列表。
比起把所有东西都放在 useEffect hook() 中,我更喜欢这样做,因为你放在里面的任何东西都会成为它的局部变量,你不能在 useEffect() 钩子之外使用它。