Reactjs 通过addEventListener调用函数时,反应状态不正确

Reactjs 通过addEventListener调用函数时,反应状态不正确,reactjs,state,Reactjs,State,我有一个React组件,如果表单输入被更新,它使用state来管理已更改的变量 假设我已经对表单进行了一些更新,我遇到的问题是,如果我使用addEventListener向onCancel函数发送一个click事件,changed的值不正确,但是如果我从JSX调用onCancel,则该值是正确的 有什么想法吗 const Edit = (props) => { let [changed, setChanged] = useState(false); // Fired when a

我有一个React组件,如果表单输入被更新,它使用state来管理
已更改的
变量

假设我已经对表单进行了一些更新,我遇到的问题是,如果我使用
addEventListener
onCancel
函数发送一个click事件,
changed
的值不正确,但是如果我从JSX调用
onCancel
,则该值是正确的

有什么想法吗

const Edit = (props) => {
  let [changed, setChanged] = useState(false);

  // Fired when a form value is updated
  const onChange = (e) => {
    setChanged("true");
  };

  // Close modal
  const onCancel = () => {
    console.log(changed); // This will be false when triggered from addEventListener
  };

  useEffect(() => {
    let form = document.querySelector(".oda-edit-form");
    // Close Window on click outside
    form.addEventListener("click", function () {
      onCancel();
    });
  }, []);

  return (
    <div>
      <input type="text" onChange={(e) => onChange(e)} />
      <button onClick={onCancel}>Close</button>
    </div>
  );
};
const Edit=(道具)=>{
let[changed,setChanged]=useState(false);
//在更新表单值时激发
const onChange=(e)=>{
设定变更(“真实”);
};
//闭合模态
const onCancel=()=>{
console.log(已更改);//当从addEventListener触发时,这将为false
};
useffect(()=>{
let form=document.querySelector(“.oda编辑表单”);
//单击“外部”关闭窗口
form.addEventListener(“单击”),函数(){
onCancel();
});
}, []);
返回(
onChange(e)}/>
接近
);
};

您需要在状态更改后立即重新呈现组件,以运行onCancel()功能

let form=document.querySelector(“.oda编辑表单”);
//单击“外部”关闭窗口
form.addEventListener(“单击”),函数(){
onCancel();
});
},[更改];/<----增加依赖性

删除了
addEventListener
,并使用自定义方法将
onClick
直接添加到JSX

const Edit = (props) => {
  let [changed, setChanged] = useState(false);

  // Fired when a form value is updated
  const onChange = (e) => {
    setChanged("true");
  };

  // Close modal
  const onCancel = () => {
    console.log(changed); // This will be false when triggered from addEventListener
  };

  const onClickOutside = (e) => {
    let element = e.target.querySelector('.wide-card');
    let isClickInside = element.contains(event.target);
    // // Close Modal
    if (!isClickInside) {
        onCancel();
    }
   };

  return (
    <div onClick-{(e)=>onClickOutside(e)}>
      <input type="text" onChange={(e) => onChange(e)} />
      <button onClick={onCancel}>Close</button>
    </div>
  );
};
const Edit=(道具)=>{
let[changed,setChanged]=useState(false);
//在更新表单值时激发
const onChange=(e)=>{
设定变更(“真实”);
};
//闭合模态
const onCancel=()=>{
console.log(已更改);//当从addEventListener触发时,这将为false
};
const onClickOutside=(e)=>{
让元素=e.target.querySelector('.wide-card');
让isClickInside=element.contains(event.target);
////关闭模式
如果(!isClickInside){
onCancel();
}
};
返回(
onclickout(e)}>
onChange(e)}/>
接近
);
};

谢谢,这很有效。此方法不会多次添加事件侦听器吗?您可以添加一个将此事件侦听器分配给常量(例如eventID)的方法。然后返回带有removeEventListener(eventID)的useEffect函数,这样每次卸载时它都会将其删除我决定重构,因为我在这里没有使用正确的方法。我将onClick直接添加到容器中,并创建了一个处理单击的新方法。谢谢你的帮助。
const Edit = (props) => {
  let [changed, setChanged] = useState(false);

  // Fired when a form value is updated
  const onChange = (e) => {
    setChanged("true");
  };

  // Close modal
  const onCancel = () => {
    console.log(changed); // This will be false when triggered from addEventListener
  };

  const onClickOutside = (e) => {
    let element = e.target.querySelector('.wide-card');
    let isClickInside = element.contains(event.target);
    // // Close Modal
    if (!isClickInside) {
        onCancel();
    }
   };

  return (
    <div onClick-{(e)=>onClickOutside(e)}>
      <input type="text" onChange={(e) => onChange(e)} />
      <button onClick={onCancel}>Close</button>
    </div>
  );
};