Reactjs 在“addEventListener”中处理单击时,单击时的状态更改只发生一次。[反应挂钩]
我想将第三方状态小部件添加到页面。我正在使用Reactjs 在“addEventListener”中处理单击时,单击时的状态更改只发生一次。[反应挂钩],reactjs,react-hooks,Reactjs,React Hooks,我想将第三方状态小部件添加到页面。我正在使用addEventListener处理单击,因为onClick不起作用(第三方代码已经在处理单击,我需要覆盖它)。但由于某些原因,组件仅在第一次单击时才重新加载。然后,即使单击事件发生(它记录在控制台中),状态也不会更新,组件也不会重新启动 我尝试使用React.useCallback来管理状态,但没有解决问题 const StatusWidget = () => { const [selected, setSelected] = useState
addEventListener
处理单击,因为onClick
不起作用(第三方代码已经在处理单击,我需要覆盖它)。但由于某些原因,组件仅在第一次单击时才重新加载。然后,即使单击事件发生(它记录在控制台中),状态也不会更新,组件也不会重新启动
我尝试使用React.useCallback
来管理状态,但没有解决问题
const StatusWidget = () => {
const [selected, setSelected] = useState(false);
const ref = useRef(null);
const toggleClass = () => {
console.log('clicked');
popup.setAttribute('data-open', !selected);
setSelected(!selected);
};
useEffect(() => {
new Status.Widget({
hostname: 'exmple.hostname',
selector: '#status',
css: true,
privacyBypassToken: 'some token',
includePrivacyBypassTokenInLinks: true,
debug: false
});
popup = document.querySelector('.status-widget__pane');
[ref.current, popup].forEach(el => el.addEventListener('click', () => toggleClass()));
},[]);
return (
<div id='status' ref={ref} className={cx(selected && 'selected')} />
);
};
export default StatusWidget;
const StatusWidget=()=>{
const[selected,setSelected]=使用状态(false);
const ref=useRef(null);
常量切换类=()=>{
console.log('clicked');
popup.setAttribute('data-open',!selected);
setSelected(!selected);
};
useffect(()=>{
新状态小部件({
主机名:“example.hostname”,
选择器:“#状态”,
css:是的,
privacyBypassToken:“某个令牌”,
IncludePrivacyBypassTokenInLink:true,
调试:false
});
popup=document.querySelector('.status-widget__窗格');
[ref.current,popup].forEach(el=>el.addEventListener('click',()=>toggleClass());
},[]);
返回(
);
};
导出默认状态控件;
问题
这里的问题是初始选定的
状态的外壳陈旧,因此您将始终从初始渲染中的相同旧值切换,并且后续渲染周期不会看到更新状态
解决方案
使用功能状态更新将前一状态的状态更新排队,而不是包含该状态的渲染周期中的状态
const toggleClass = () => {
console.log('clicked');
popup.setAttribute('data-open', !selected);
setSelected(selected => !selected); // <-- functional state update.
};
useEffect(() => {
new Status.Widget({
hostname: 'exmple.hostname',
selector: '#status',
css: true,
privacyBypassToken: 'some token',
includePrivacyBypassTokenInLinks: true,
debug: false
});
popup = document.querySelector('.status-widget__pane');
[ref.current, popup].forEach(el => el.addEventListener('click', toggleClass));
return () => {
[ref.current, popup].forEach(el => el.removeEventListener('click', toggleClass));
};
},[]);