javascript - 当 React 运行代码两次时,如何为反应组件提供动态 ID?
问题描述
代码运行两次是一种已知的 React 行为。
但是,我正在创建一个表单构建器,在其中我需要能够为每个表单输入提供一个动态 Id,并在以后将该 Id 用于许多其他目的。这是一个简单的输入代码:
const Text = ({placeholder}) => {
const [id, setId] = useState(Math.random());
eventEmitter.on('global-event', () => {
var field = document.querySelector(`#${id}`); // here, id is changed
});
}
但由于Math.random()
是副作用,它被调用了两次,我无法为我的表单字段创建动态 ID。
我使用的原因document.querySelector
可以在这里阅读。
我的问题是,如何为我的输入创建一致的动态 ID?
解决方案
您似乎认为这useState(Math.random());
是导致您问题的副作用,但只有传递给的函数才会useState
被双重调用。
我认为您遇到的问题是eventEmitter.on
调用是无意的副作用,因为函数组件主体也被双重调用。
严格模式不能自动为您检测副作用,但可以通过使它们更具确定性来帮助您发现它们。这是通过有意双重调用以下函数来完成的:
- 类组件
constructor
,render
和shouldComponentUpdate
方法- 类组件静态
getDerivedStateFromProps
方法- 函数组件体<--this
- 状态更新函数( 的第一个参数
setState
)- 传递给
useState
、useMemo
或useReducer
< 的函数——不是 this
为了解决这个问题,我认为您应该将eventEmitter.on
逻辑放入useEffect
依赖于id
状态的钩子中。您还应该使用id
可以保证更多唯一性的值。不要忘记从效果中返回一个清理函数以删除任何活动的事件“侦听器”,无论是在id
更新时,还是在组件卸载时。这是为了帮助清除任何资源泄漏(内存、套接字等)。
例子:
import { v4 as uuidV4 } from 'uuid';
const Text = ({placeholder}) => {
const [id, setId] = useState(uuidV4());
useEffect(() => {
const handler = () => {
let field = document.querySelector(`#${id}`);
};
eventEmitter.on('global-event', handler);
return () => {
eventEmitter.removeListener('global-event', handler);
};
}, [id]);
...
}
推荐阅读
- sockets - 当我在输出通道上调用 `close_out` 时,为什么会出现 Sys_error("Bad file descriptor")?
- python - 为特定环境创建 Visual Studio Code (VSCode) 终端
- javascript - 如何将循环的每次迭代包装在单独的 div 容器中
- dll - 自定义 Taghelper 在 viewcoponent 的查看页面中不起作用
- c# - 如何在视图 #1 中按下按钮以更改视图 #2 中的标签(Xamarin iOS)
- c++ - Coursera 自动评分器给了我未知信号 11
- javascript - 如何点击非浏览器区域关闭JS生成的右键菜单?
- php - 未定义的索引 $_SERVER['SOME_CUSTOM_SYSTEM_VAR'] 仅适用于生产 AWS 环境
- java - Java:0 arg 构造函数和构造函数的问题
- r - 当我在散点图中将轴的原点设置为零时,点会被切断