我试图了解为什么在从React组件中使用此闭包时无法按预期工作。
// state.ts
const state = { things: [] };
export function setThings(newThings: number[]) {
state.things = newThings;
}
// App.tsx
import { setThings } from "./state";
function App() {
const setThingsToArray = () => setThings([0, 1, 2]);
return (
<div>
<button onClick={setThingsToArray}>Set things</button>
</div>
);
}
从非反应代码中调用setThings
时,它可以正常工作。它将更改things
的{{1}}属性。
但是,当我尝试从React组件(如App.tsx)中调用它时,它根本不起作用。调试显示,从state
内部调用setThings
时,它认为App
是一个空数组state.things
,即使{{1} }已经包含很多项目。
这似乎暗示React在某种程度上使用了[]
的复制版本和state.things
的复制版本。这怎么可能?它不应该作为简单的闭包并引用实际的setThings
吗?
我不想使用像Hooks或Redux这样的React状态管理,因为我希望对数组中的更改具有高性能,因为这为具有大量粒子和每秒重绘的画布应用程序提供了动力。因此,如果我不需要React组件来显示数据,我就不必经历整个React生命周期。
编辑:为这个问题?♂️编写组件代码时,我犯了一个错误。我现在修复了。我的问题仍然存在。
编辑2:
因为@KevinB要求提供证据证明在其他地方调用state
可以正确更新我的数组:https://youtu.be/Gp77NtqNQzo
画布中的每个“行星”都由数组中的一项表示。每个行星的坐标和加速度在每个帧上都会改变。当行星发生碰撞时,state
被更改的行星阵列调用。之所以需要这样做,是因为多个行星可以彼此“碰撞”并合并为一个,从而形成setThings
数组,其中删除了2个项,并添加了1个新项。
单击按钮将调用setThings
,该数组仅包含一个行星对象。但正如您所见,它什么也没做。
答案 0 :(得分:1)
您不会在state.ts中从setThings
返回任何内容
但是您正在将其分配给App.tsx中的const setThings
在<button onClick={setThings}>
上,您引用的setThings
是您拨打的电话中的undefined
返回。
尝试像这样为<button>
分配实际功能:
// App.tsx
import { setThings } from "./state";
function App() {
const setThingsClickHandler = () => {
setThings([0, 1, 2]);
};
return (
<div>
<button onClick={setThingsClickHandler}>Set things</button>
</div>
);
}
答案 1 :(得分:0)
事实证明,因为我是直接通过两个单独的main.ts
标签从HTML文件中导入App.tsx
和<script>
的,所以Parcel为它们创建了两个完全独立的包,这意味着是每个捆绑软件中单独的state
对象。
这就是为什么更新一个不会影响另一个的原因。 ?