React-DOM 自动触发 onClick 处理程序
React-DOM automatically triggering onClick handler
我有一个 react-modal 显示了一些过滤器。它接受一个 isOpen
道具,该道具根据值隐藏或显示模式。
Modal
点击'Apply'按钮成功打开,但点击'Cancel'没有关闭。
//Click Handlers in the parent component (filters.js)
openAllFilters = () => {
this.setState({ showAllFilters: true });
};
closeAllFilters = () => {
this.setState({ showAllFilters: false }, () =>
console.log("state ", this.state.showAllFilters)
); // logs true!);
};
<AllFilters isOpen={this.state.showAllFilters}
closeAllFilters={this.closeAllFilters}
onRequestClose={this.closeAllFilters}
renderAbcFilter={this.renderAbcFilter}
renderDefFilter={this.renderDefFilter}
renderXyzFilter={this.renderXyzFilter}
/>
模态组件(AllFilters.js):
import React from 'react';
import Modal from 'react-modal';
const RenderFilter = props => {
return <div className="filter-wrapper">
<h3 className="filter-title">{props.title}</h3>
{props.renderFunction()}
</div>;
}
const AllFilters = (props) => {
const modalStyles = {
overlay: {
zIndex: 200,
},
content: {
top: '0',
left: '0',
right: '0',
bottom: '0',
padding: '0',
}
};
return (
<Modal isOpen={props.isOpen}
style={modalStyles}
onRequestClose={props.closeAllFilters}>
<div className="all-filters-container">
<RenderFilter title='ABC' renderFunction={() => props.renderAbcFilter(false)} />
<RenderFilter title='XYZ' renderFunction={() => props.renderXyzFilter(false)} />
<RenderFilter title='DEF' renderFunction={() => props.renderDefFilter(false)} />
</div>
<div className="all-filters-footer">
<button className="button button-secondary filter-cancel-btn " onClick={props.closeAllFilters}>CANCEL</button>
</Modal >
)
}
export default AllFilters;
我不明白为什么调用closeAllFilters
时state
没有更新为false
?
编辑:closeAllFilters
确实在单击 'Cancel' 按钮时被调用。 console.log(this.state.showAllFilters)
输出 true
!。尽管这是 setState
回调!
EDIT2:我认为 openAllfilters
在 closeAllFilters
被调用后会以某种方式自动被调用。因此它将 showAllFilters
设置回 true
并且模式保持打开状态。更新了问题标题以更好地反映问题。相同的堆栈跟踪如下:
openAllFilters (filters.js#382)
callCallback (react-dom.development.js#149)
invokeGuardedCallbackDev (react-dom.development.js#199)
invokeGuardedCallback (react-dom.development.js#256)
invokeGuardedCallbackAndCatchFirstError (react-dom.development.js#270)
executeDispatch (react-dom.development.js#561)
executeDispatchesInOrder (react-dom.development.js#580)
executeDispatchesAndRelease (react-dom.development.js#680)
executeDispatchesAndReleaseTopLevel (react-dom.development.js#688)
forEachAccumulated (react-dom.development.js#662)
runEventsInBatch (react-dom.development.js#816)
runExtractedEventsInBatch (react-dom.development.js#824)
handleTopLevel (react-dom.development.js#4826)
batchedUpdates (react-dom.development.js#20439)
batchedUpdates (react-dom.development.js#2151)
dispatchEvent (react-dom.development.js#4905)
1 (react-dom.development.js#20490)
unstable_runWithPriority (scheduler.development.js#255)
interactiveUpdates (react-dom.development.js#20489)
interactiveUpdates (react-dom.development.js#2170)
dispatchInteractiveEvent (react-dom.development.js#4882)
从上面的调用堆栈来看,React 似乎以某种方式触发了 openAllFilters
。我一个一个地经历了这些函数调用,但仍然无法弄清楚为什么会这样。也许了解 React 源代码的人可以提供一些见解..
所以经过大量的调试和挠头,我终于弄清楚了问题是什么。由于事件传播,openAllFilters
在调用 closeAllFilters
之后被调用。通过在模式上单击 任意位置 来触发该事件。我没有找到任何道具来禁用此行为,所以这可能是 react-modal
的错误。所以唯一需要的修复是添加 e.stopPropagation()
!
所以修改后的方法变成:
closeAllFilters = (e) => {
this.setState({ showAllFilters: false });
e.stopPropagation();
}
谢谢大家的帮助!
我有一个 react-modal 显示了一些过滤器。它接受一个 isOpen
道具,该道具根据值隐藏或显示模式。
Modal
点击'Apply'按钮成功打开,但点击'Cancel'没有关闭。
//Click Handlers in the parent component (filters.js)
openAllFilters = () => {
this.setState({ showAllFilters: true });
};
closeAllFilters = () => {
this.setState({ showAllFilters: false }, () =>
console.log("state ", this.state.showAllFilters)
); // logs true!);
};
<AllFilters isOpen={this.state.showAllFilters}
closeAllFilters={this.closeAllFilters}
onRequestClose={this.closeAllFilters}
renderAbcFilter={this.renderAbcFilter}
renderDefFilter={this.renderDefFilter}
renderXyzFilter={this.renderXyzFilter}
/>
模态组件(AllFilters.js):
import React from 'react';
import Modal from 'react-modal';
const RenderFilter = props => {
return <div className="filter-wrapper">
<h3 className="filter-title">{props.title}</h3>
{props.renderFunction()}
</div>;
}
const AllFilters = (props) => {
const modalStyles = {
overlay: {
zIndex: 200,
},
content: {
top: '0',
left: '0',
right: '0',
bottom: '0',
padding: '0',
}
};
return (
<Modal isOpen={props.isOpen}
style={modalStyles}
onRequestClose={props.closeAllFilters}>
<div className="all-filters-container">
<RenderFilter title='ABC' renderFunction={() => props.renderAbcFilter(false)} />
<RenderFilter title='XYZ' renderFunction={() => props.renderXyzFilter(false)} />
<RenderFilter title='DEF' renderFunction={() => props.renderDefFilter(false)} />
</div>
<div className="all-filters-footer">
<button className="button button-secondary filter-cancel-btn " onClick={props.closeAllFilters}>CANCEL</button>
</Modal >
)
}
export default AllFilters;
我不明白为什么调用closeAllFilters
时state
没有更新为false
?
编辑:closeAllFilters
确实在单击 'Cancel' 按钮时被调用。 console.log(this.state.showAllFilters)
输出 true
!。尽管这是 setState
回调!
EDIT2:我认为 openAllfilters
在 closeAllFilters
被调用后会以某种方式自动被调用。因此它将 showAllFilters
设置回 true
并且模式保持打开状态。更新了问题标题以更好地反映问题。相同的堆栈跟踪如下:
openAllFilters (filters.js#382)
callCallback (react-dom.development.js#149)
invokeGuardedCallbackDev (react-dom.development.js#199)
invokeGuardedCallback (react-dom.development.js#256)
invokeGuardedCallbackAndCatchFirstError (react-dom.development.js#270)
executeDispatch (react-dom.development.js#561)
executeDispatchesInOrder (react-dom.development.js#580)
executeDispatchesAndRelease (react-dom.development.js#680)
executeDispatchesAndReleaseTopLevel (react-dom.development.js#688)
forEachAccumulated (react-dom.development.js#662)
runEventsInBatch (react-dom.development.js#816)
runExtractedEventsInBatch (react-dom.development.js#824)
handleTopLevel (react-dom.development.js#4826)
batchedUpdates (react-dom.development.js#20439)
batchedUpdates (react-dom.development.js#2151)
dispatchEvent (react-dom.development.js#4905)
1 (react-dom.development.js#20490)
unstable_runWithPriority (scheduler.development.js#255)
interactiveUpdates (react-dom.development.js#20489)
interactiveUpdates (react-dom.development.js#2170)
dispatchInteractiveEvent (react-dom.development.js#4882)
从上面的调用堆栈来看,React 似乎以某种方式触发了 openAllFilters
。我一个一个地经历了这些函数调用,但仍然无法弄清楚为什么会这样。也许了解 React 源代码的人可以提供一些见解..
所以经过大量的调试和挠头,我终于弄清楚了问题是什么。由于事件传播,openAllFilters
在调用 closeAllFilters
之后被调用。通过在模式上单击 任意位置 来触发该事件。我没有找到任何道具来禁用此行为,所以这可能是 react-modal
的错误。所以唯一需要的修复是添加 e.stopPropagation()
!
所以修改后的方法变成:
closeAllFilters = (e) => {
this.setState({ showAllFilters: false });
e.stopPropagation();
}
谢谢大家的帮助!