简体   繁体   English

对不改变状态的父级做出回调

[英]React callback to parent not changing state

I cannot for the life of me figure out why this isn't working.我一生都无法弄清楚为什么这不起作用。 I have a WorkoutCard component:我有一个 WorkoutCard 组件:

WorkoutCard:锻炼卡:

const key = require('weak-key');

function WorkoutCard({ workout }) {

  const { userID } = useContext(AuthContext);
  const [modalOpen, setModalOpen] = useState(false);
  const closeModalCallback = () => setModalOpen(false);

  return (
    <div className="WorkoutCard" onClick={() => setModalOpen(true)}>
      <div className="header">
        <h2>{workout.name}</h2>
        <h3>Days</h3>
        {workout.days.map((day) => {
          return (
            <p key={key({})}>{day}</p>
          )
        })}
        <button className="deleteButton" onClick={handleDelete}>Delete</button>
      </div>

      <div className="line"></div>

      <div className="exercises">
        <h3>Exercises</h3>
        {workout.exercises.map((exercise) => {
          return (
            <p key={key({})}>{exercise}</p>
          )
        })}
      </div>

      <EditWorkoutModal key={key({})} modalOpen={modalOpen} closeModalCallback={closeModalCallback} />
    </div>
  );
}

export default WorkoutCard;

And I have the EditWorkoutModal component:我有 EditWorkoutModal 组件:

Modal.setAppElement('#root');

function EditWorkoutModal({ modalOpen, workout, closeModalCallback }) {

  const { userID } = useContext(AuthContext);

  return (
    <Modal isOpen={modalOpen} className="editModal">
      <div className="rightHalf">
        <p className='closeButton' onClick={() => closeModalCallback()}>+</p>
      </div>
    </Modal>
  )
}

export default EditWorkoutModal

The problem here is that closeModalCallback is not changing the state whatsoever.这里的问题是 closeModalCallback 并没有改变状态。 It is called, but modalOpen is still set to true.它被调用,但 modalOpen 仍然设置为 true。

And, this is even more confusing, because I have this functionality working in another part of the app.而且,这更令人困惑,因为我有这个功能在应用程序的另一部分工作。 I have a workouts page that has both WorkoutCard components, as well as a Modal, and it works this way.我有一个包含 WorkoutCard 组件和 Modal 的锻炼页面,它以这种方式工作。 However, the closeModalCallback on the WorkoutCard components' modals will not work.但是,WorkoutCard 组件的模式上的 closeModalCallback 将不起作用。

onClick events bubble up the DOM. onClick事件使 DOM 冒泡。 For example, see the below snippet (see browser console for output):例如,请参阅以下代码段(请参阅浏览器控制台以获取输出):

 const App = () => { const parent = () => console.log("parent"); const child = () => console.log("child"); return <div onClick={parent}> <div onClick={child}>Click me</div> </div> } ReactDOM.createRoot(document.body).render(<App />);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.0.0/umd/react-dom.production.min.js"></script>

The above logs the following in the console:以上在控制台中记录了以下内容:

> child
> parent

When you click on your child element, the click event bubbles up the DOM, eventually reaching your div with the WorkoutCard class, which fires the onClick that sets your modal-open state to true .当您单击子元素时,单击事件会在 DOM 中冒泡,最终通过WorkoutCard类到达您的div ,该类会触发将您的模式打开状态设置为trueonClick You can stop the event from bubbling by calling e.stopPropagation() on your close-modal button:您可以通过在关闭模式按钮上调用e.stopPropagation()来阻止事件冒泡:

onClick={(e) => {
  e.stopPropagation();
  closeModalCallback();
}}

This way the event won't bubble up to your parent div and trigger the onClick which is changing your state.这样,事件就不会冒泡到您的父 div 并触发正在更改您的状态的onClick

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM