gpt4 book ai didi

javascript - 我似乎无法使用 componentWillUnmount 可靠地删除监听器

转载 作者:行者123 更新时间:2023-11-29 18:02:36 33 4
gpt4 key购买 nike

我在窗口中添加了一个监听器来检测 onClickOutside 类型的场景(具体来说,当在菜单外单击时折叠菜单)。这是带有相关代码的组件:

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import LinkedStateMixin from 'react-addons-linked-state-mixin';
import styles from './DescriptiveSelect.css';
import classNames from 'classnames';
import _ from 'underscore';

export default class DescriptiveSelect extends Component {

static propTypes = {
attrForOptionLabel: PropTypes.string,
attrForOptionValue: PropTypes.string,
children: PropTypes.string,
className: PropTypes.string,
disabled: PropTypes.bool,
nullLabel: PropTypes.string,
onUpdate: PropTypes.func,
options: PropTypes.array,
selectedLabel: PropTypes.string,
selectedOption: PropTypes.number,
valueLink: PropTypes.object
}

mixins: [LinkedStateMixin]

static defaultProps = {
attrForOptionLabel: 'name',
attrForOptionValue: 'id',
disabled: false,
selectedOption: 0,
selectedLabel: 'Select one…'
}

state = {
isOpen: false,
options: []
}

componentDidMount() {
this.buildOptions(this.props.options);
window.addEventListener('click', this.onDocumentClick.bind(this));
}

componentWillUnmount() {
window.removeEventListener('click', this.onDocumentClick);
}

onDocumentClick(event) {
const theLabel = ReactDOM.findDOMNode(this);

if (theLabel && theLabel.contains(event.target)) {
this.setState({isOpen: !this.state.isOpen});
} else {
this.setState({isOpen: false});
}
event.preventDefault();
}

handleSelection(option) {
if (this.props.onUpdate) {
this.props.onUpdate(option.id);
}
this.setState({'isOpen': false});
}

/**
* Build out <select> menu options
* Data must be formatted with the following attributes:
* const theData = [
* {
* id: 1,
* sequence: 0,
* short_name: 'App'
* }
* ];
* @param {array} data The data to convert, either from an endpoint
* response or passed in via the `options` prop.
*/
buildOptions(data) {
const _this = this;
const results = data;
const resultLength = results.length;
const {
attrForOptionValue,
attrForOptionLabel
} = this.props;

// Sort data by sequence attribute
_.sortBy(results, 'sequence');

// Cycle through JSON results and create <option> elements
for (let i = 0; i < resultLength; i++) {
const option = results[i];
_this.state.options.push(
<option key={option.id} value={option[attrForOptionValue]}>{option[attrForOptionLabel]}</option>
);
_this.forceUpdate();
}
}

render() {
const {
className,
nullLabel,
options
} = this.props;

// Classes for select menu
const selectClasses = classNames({
[styles.LabelWrapper]: true,
[className]: className
});

/**
* Contents of the custom select.
* Taken from the `options` prop that should be passed in.
*/
const optionNodes = options.map((option) => {
return (
<li className={styles.Option} key={option.id} onClick={this.handleSelection.bind(this, option)}>
<div className={styles.OptionLabel}>a <strong>{option.name}</strong></div>
<div className={styles.OptionDetail}>{option.description}</div>
</li>
);
});

return (
<label className={selectClasses} ref="theLabel">
<select
className={styles.Select}
nullLabel={nullLabel}
options={options}
ref="theSelect"
valueLink={this.props.valueLink}
>
{ nullLabel ? <option value="">{nullLabel}</option> : null }
{ this.state.options }
</select>
{ this.state.isOpen ? <div className={styles.Menu}>
<ul className={styles.OptionsWrapper}>
{optionNodes}
</ul>
<footer className={styles.Footer}>
<p><a href="#">Learn more</a> about App.typography titles.</p>
</footer>
</div> : null }
</label>
);
}
}

我不确定为什么,但它并没有真正删除监听器,所以我最终在控制台中得到了其中的几个:

Uncaught Error: Invariant Violation: findDOMNode was called on an unmounted component.

这段代码中有什么明显的地方可能导致了这个问题吗?

最佳答案

您正在尝试删除未绑定(bind)的函数。 .bind 返回一个 函数,即 this.onDocumentClick.bind(this) !== this.onDocumentClick

您应该在构造函数中绑定(bind)一次该方法,然后在整个过程中使用该方法:

constructor(props) {
super(props);
this.onDocumentClick = this.onDocumentClick.bind(this);
// use this.onDocumentClick everywhere
}

关于javascript - 我似乎无法使用 componentWillUnmount 可靠地删除监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33808808/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com