去抖动实施

时间:2017-10-02 07:49:05

标签: reactjs

我在实施lodash时遇到了困难:

我正在努力使我的输入字段触发我的检查,如果在击键结束后每秒都存在API调用,而不是每秒。

(我稍后将updateInput函数分开,以便首先设置输入值,然后调用我应该创建的去抖动API调用方法。)

import React, { Component } from 'react';
import _ from 'lodash';
import { Input, Row, Col } from 'reactstrap';
import loading from '../../../../img/loading.gif';

class InputTypeComponent extends Component {

    constructor(props) {
        super(props);
        const initialValue = props.value;
        this.state = {
            ...initialValue,
        };
        this.updateInput = this.updateInput.bind(this);
        this.handleProviderChange = this.handleProviderChange.bind(this);
        this.updateInput = _.debounce(this.updateInput, 1000);
    }

componentWillMount() {
    this.setState({ inputIcon: this.props.icon.inputIcon });
}

componentWillReceiveProps(newProps) {
    const response = newProps.response;
    const old = this.props.response;
    const { id, onChange } = this.props;
    if (response !== old && response.objectIdentifier === id) {
        let number = 2;
        if (response.objectName === '') {
            number = 0;
        } else if (response.activ) {
            if (response.isthere) {
                number = 4;
            } else {
                number = 3;
            }
        }
        this.setState({ inputIcon: number });
        onChange({ icon: {
            ...this.props.icon,
            inputIcon: number,
        } }, this.props.id);
    }
}

onRemove = () => {
    this.props.onRemove(this.props.id);
};

onChange = () => {
    this.props.onChange(this.props.id);
};

updateInput(event) {
    const { onChange, exists } = this.props;
    const inputValue = event.target.value.toUpperCase();
    this.setState({ input: inputValue });
    onChange({ value: {
        ...this.state,
        input: inputValue,
    } }, this.props.id);
    const placeHolder = this.props.placeholder.toLowerCase();
    const objectIdentifier = this.props.id;
    const payload = {
        objectType: placeHolder,
        objectName: inputValue,
        objectIdentifier,
        objectFisrt: '',
    };
    exists(payload);
}

render() {
    const { placeholder, provider, size } = this.props;
    const { inputIcon } = this.state;
    this.type = placeholder;
    return (
        <Row>
            <Col xs="8">
                <Row>
                    <Col xs="11">
                        <Input
                            value={this.state.input}
                            onChange={this.updateInput}
                            placeholder={placeholder}
                        />
                    </Col>
                    <Col xs="1" className="margintop noPadding">
                        {{
                            0: (
                                <div />
                            ),
                            1: (
                                <img className="colorImgBlue" src={loading} alt="loading" />
                            ),
                            2: (
                                <i className="fa fa-times red iconsize" />
                            ),
                            3: (
                                <i className="fa fa-check text-success iconsize" />
                            ),
                            4: (
                                <i className="fa fa-check text-success iconsize" />
                            ),
                            default: (
                                <div />
                            ),
                        }[inputIcon]}
                    </Col>
                </Row>
           </Col>
      </Row>
   );
}

这破坏了我的代码,现在UpdateInput函数永远不会触发。

所有这些的文档和博客都是sparce所以我无处可去。

enter image description here

1 个答案:

答案 0 :(得分:2)

错误消息实际上是指出错误的原因:

  

警告:出于性能原因,会重复使用此合成事件。如果您看到这个,那么您将在已发布/无效的合成事件上访问属性target。这被设置为null ...请参阅fb.me/react-event-pooling

React为您管理所有DOM事件,并作为其内部性能优化的一部分,它维护一个事件池,并在新事件进入时重新使用这些对象。但是,当React完成时,将事件传递给组件树它使所有字段都为空。

在React清除了共享事件对象后,当您仅推迟updateInput lodash 调用 updateInputs时。

解决这个问题的方法是将你的方法分为两部分 - 第一部分抓住合成事件所需的信息,第二部分实际完成你想要去除的工作:

constructor() {
  this.onInput = this.onInput.bind(this);
  this.updateInput = _.debounce(this.updateInput.bind(this), 1000);
}
onInput(event) {
  const inputValue = event.target.value.toUpperCase();
  this.updateInput(inputValue);
}
updateInput(inputValue) {
  // Details omitted for brevity
}