反应回调到父不改变状态
React callback to parent not changing state
我一辈子都弄不明白为什么这不起作用。我有一个 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;
我有 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
这里的问题是 closeModalCallback 没有改变任何状态。它被调用,但 modalOpen 仍设置为 true。
而且,这更令人困惑,因为我在应用程序的另一部分使用了此功能。我有一个包含 WorkoutCard 组件和模式的锻炼页面,它以这种方式工作。但是,WorkoutCard 组件模态上的 closeModalCallback 将不起作用。
onClick
事件冒出 DOM。例如,请参阅以下代码片段(请参阅浏览器控制台以获取输出):
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>
以上在控制台中记录以下内容:
> child
> parent
当您点击 child 元素时,点击事件会向上冒泡 DOM,最终到达 div
和 WorkoutCard
class,这会触发 onClick
,将您的 modal-open 状态设置为 true
。您可以通过在 close-modal 按钮上调用 e.stopPropagation()
来阻止事件冒泡:
onClick={(e) => {
e.stopPropagation();
closeModalCallback();
}}
这样事件就不会冒泡到你的 parent div 并触发正在改变你的状态的 onClick
。
我一辈子都弄不明白为什么这不起作用。我有一个 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;
我有 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
这里的问题是 closeModalCallback 没有改变任何状态。它被调用,但 modalOpen 仍设置为 true。
而且,这更令人困惑,因为我在应用程序的另一部分使用了此功能。我有一个包含 WorkoutCard 组件和模式的锻炼页面,它以这种方式工作。但是,WorkoutCard 组件模态上的 closeModalCallback 将不起作用。
onClick
事件冒出 DOM。例如,请参阅以下代码片段(请参阅浏览器控制台以获取输出):
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>
以上在控制台中记录以下内容:
> child
> parent
当您点击 child 元素时,点击事件会向上冒泡 DOM,最终到达 div
和 WorkoutCard
class,这会触发 onClick
,将您的 modal-open 状态设置为 true
。您可以通过在 close-modal 按钮上调用 e.stopPropagation()
来阻止事件冒泡:
onClick={(e) => {
e.stopPropagation();
closeModalCallback();
}}
这样事件就不会冒泡到你的 parent div 并触发正在改变你的状态的 onClick
。