首次搜索时,自定义自动完成组件不显示输出

时间:2019-05-11 14:52:16

标签: reactjs react-redux

我已经创建了自定义的自动完成(Autosuggestions)组件。当我将字符串的硬编码数组传递给自动完成组件时,一切工作都很好,但是当我尝试从API作为道具传递数据时,第一次搜索没有任何结果。每次都在第一次之后精确显示结果

我尝试了不同的选项,但是当用户第一次搜索数据时似乎不存在,并且自动完成功能以空数组呈现。我已经测试了相同的API端点,并且每次返回时都会返回数据。

具有自动完成功能的首页组件

        const filteredUsers = this.props.searchUsers.map((item) => item.firstName).filter((item) => item !== null);

        const autocomplete = (
            <AutoComplete
                items={filteredUsers}
                placeholder="Search..."
                label="Search"
                onTextChanged={this.searchUsers}
                fieldName="Search"
                formName="autocomplete"
            />
        );

自动完成组件可过滤插入的数据并显示建议列表,问题可能出在onTextChange内:

export class AutoComplete extends Component {
    constructor(props) {
        super(props);
        this.state = {
            suggestions: [],
            text: '',
        };
    }

    // Matching and filtering suggestions fetched from the backend and text that user has entered
    onTextChanged = (e) => {
        const value = e.target.value;
        let suggestions = [];
        if (value.length > 0) {
            this.props.onTextChanged(value);
            const regex = new RegExp(`^${value}`, 'i');
            suggestions = this.props.items.sort().filter((v) => regex.test(v));
        }
        this.setState({ suggestions, text: value });
    };

    // Update state each time user press suggestion
    suggestionSelected = (value) => {
        this.setState(() => ({
            text: value,
            suggestions: []
        }));
    };

    // User pressed the enter key
    onPressEnter = (e) => {
        if (e.keyCode === 13) {
            this.props.onPressEnter(this.state.text);
        }
    };

    render() {
        const { text } = this.state;
        return (
            <div style={styles.autocompleteContainerStyles}>
                <Field
                    label={this.props.placeholder}
                    onKeyDown={this.onPressEnter}
                    onFocus={this.props.onFocus}
                    name={this.props.fieldName}
                    formValue={text}
                    onChange={this.onTextChanged}
                    component={RenderAutocompleteField}
                    type="text"
                />
                <Suggestions
                    suggestions={this.state.suggestions}
                    suggestionSelected={this.suggestionSelected}
                    theme="default"
                />
            </div>
        );
    }
}

const styles = {
    autocompleteContainerStyles: {
        position: 'relative',
        display: 'inline',
        width: '100%'
    }
};

AutoComplete.propTypes = {
    items:  PropTypes.array.isRequired,
    placeholder: PropTypes.string.isRequired,
    onTextChanged: PropTypes.func.isRequired,
    fieldName: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    onPressEnter: PropTypes.func.isRequired,
    onFocus: PropTypes.func
};

export default reduxForm({
    form: 'Autocomplete'
})(AutoComplete);

预期结果:每次用户使用textinput搜索时,他应该获得建议结果 实际结果:首次用户使用textinput搜索时,他没有获取数据。只有在有首次数据之后

1 个答案:

答案 0 :(得分:1)

它在硬编码时有效,但在使用API​​时无效,因为您的过滤发生在onTextChanged中。进行硬编码后,您的AutoComplete具有可以在首次调用onTextChangedthis.props.items.sort().filter(...)时使用的值,但是使用API​​时,items道具将为空,直到您使用API返回-完成此功能后。

为了处理来自API的结果,您需要在道具更改时进行过滤。 react文档实际上涵盖了非常相似的情况here(请参见第二个示例,因为第一个示例显示了getDerivedStateFromProps的使用不必要地复杂),重要的部分是他们使用了PureComponent来避免不必要的重新渲染,然后在渲染中进行过滤,例如在您的情况下:

render() {
  // Derive your filtered suggestions from your props in render - this way when your API updates your items prop, it will re-render with the new data
  const { text } = this.state;
  const regex = new RegExp(`^${text}`, 'i');
  suggestions = this.props.items.sort().filter((v) => regex.test(v));

  ...
  <Suggestions
    suggestions={suggestions}
    ...
  />
  ...
}