点击邮件详情触发事件
先触发
Mailspring/app/src/components/list-tabular-item-dynamic.tsx
下面的_onClick
执行
if (typeof this.props.onSelect === 'function') {this.props.onSelect(this.props.item, event);
}
执行 Mailspring/app/src/components/list-tabular-item.tsx下面的_onClickItem
_onClickItem = (item, event) => {if (!this.state.handler) {return;}if (event.metaKey || event.ctrlKey) {this.state.handler.onMetaClick(item);} else if (event.shiftKey) {this.state.handler.onShiftClick(item);} else {this.state.handler.onClick(item);}};
命中_onClickItem中的this.state.handler.onClick(item)
触发 Mailspring/app/src/components/multiselect-split-interaction-handler.ts中onClick
onClick = item => {this.onFocusItem(item);this.props.dataSource.selection.clear();this._checkSelectionAndFocusConsistency();};
this.onFocusItem = props.onFocusItem
在 Mailspring/app/src/components/multiselect-list-dynamic.tsx中
_getStateFromStores(props = this.props) {let computedColumns, handler;const state: Partial<MultiselectListState> = this.state || {};const layoutMode = WorkspaceStore.layoutMode();// Do we need to re-compute columns? Don't do this unless we really have to,// it will cause a re-render of the entire ListTabular. To know whether our// computed columns are still valid, we store the original columns in our state// along with the computed ones.if (props.columns !== state.columns || layoutMode !== state.layoutMode) {computedColumns = [...props.columns];if (layoutMode === 'list') {computedColumns.splice(0, 0, this._getCheckmarkColumn());}} else {({ computedColumns } = state);}if (layoutMode === 'list') {handler = new MultiselectListInteractionHandler(props);} else {handler = new MultiselectSplitInteractionHandler(props);}return {handler,columns: props.columns,computedColumns,layoutMode,};}
handler = new MultiselectSplitInteractionHandler(props);
那么MultiselectSplitInteractionHandler中的props也就是multiselect-list-dynamic的props
lazyLoad('MultiselectListDynamic', 'multiselect-list-dynamic');
multiselect-list-dynamic也就是MultiselectListDynamic
只有Mailspring/app/internal_packages/thread-list/lib/thread-list.tsx中用到MultiselectListDynamic
<FocusContainer collection="thread"><MultiselectListDynamicref="listDynamic"containerRef={this._rootDynamicRef}footer={this._getFooter()}draggablecolumns={[...ThreadListColumns.AI]}itemPropsProvider={this._threadPropsProvider}className={`thread-list thread-list-${this.state.style} bg-[url(images/sidebar/sidebar-switcher-bg@2x.png)] bg-repeat`}scrollTooltipComponent={ThreadListScrollTooltip}EmptyComponent={EmptyListState}currentTab={this.state.tab}onScrollEnd={this._onAiListScrollEnd}keymapHandlers={{'thread-list:select-read': this._onSelectRead,'thread-list:select-unread': this._onSelectUnread,'thread-list:select-starred': this._onSelectStarred,'thread-list:select-unstarred': this._onSelectUnstarred,'thread-list:mark-all-as-read': this._onMarkAllAsRead,}}onDoubleClick={(thread) => Actions.popoutThread(thread)}onDragItems={this._onDragItems}onDragEnd={this._onDragEnd}/></FocusContainer>
可以看到MultiselectListDynamic上并没有显式传入onFocusItem
通过断点看到进入了Mailspring/app/src/components/focus-container.tsx也就是FocusContainer组建里面。
import React from 'react';
import { PropTypes, FocusedContentStore, Actions } from 'mailspring-exports';
import { FluxContainer } from 'mailspring-component-kit';type FocusContainerProps = {collection?: string;children: React.ReactElement<any>;
};
export default class FocusContainer extends React.Component<FocusContainerProps> {static displayName = 'FocusContainer';static propTypes = {children: PropTypes.element,collection: PropTypes.string,};getStateFromStores = () => {const { collection } = this.props;return {focused: FocusedContentStore.focused(collection),focusedId: FocusedContentStore.focusedId(collection),keyboardCursor: FocusedContentStore.keyboardCursor(collection),keyboardCursorId: FocusedContentStore.keyboardCursorId(collection),onFocusItem: item => Actions.setFocus({ collection: collection, item: item }),onSetCursorPosition: item =>Actions.setCursorPosition({ collection: collection, item: item }),};};render() {return (<FluxContainer{...this.props}stores={[FocusedContentStore]}getStateFromStores={this.getStateFromStores}>{this.props.children}</FluxContainer>);}
}
可以看到FocusContainer并没有主动把onFocusItem通过props传给children,其实是通过FluxContainer这个我高阶组建实现了把onFocusItem传给children。
collection="thread"
最后触发Actions.setFocus({ collection: collection, item: item })
通过全局搜监听Actions.setFocus也就只有
Mailspring/app/src/flux/stores/focused-content-store.ts和Mailspring/app/src/flux/stores/workspace-store.ts
主要是focused-content-store中的_onFocus