Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 在“addEventListener”中处理单击时,单击时的状态更改只发生一次。[反应挂钩]_Reactjs_React Hooks - Fatal编程技术网

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));
  };
},[]);