autosuggest 不立即显示项目

autosuggest not showing item immediately

我正在研究修复代码中的错误。有一个包含许多表单字段的表单。 Project Name就是其中之一。当用户单击按钮(加号图标)时,it.So 旁边有一个按钮,弹出窗口 window 出现,用户输入 Project NameDescription 并点击提交按钮保存项目。 该表单有提交、重置和取消按钮(为简洁起见,代码中未显示)。

表单的项目名称字段具有自动建议功能。下面的代码片段显示了项目名称 field.So 的表单部分,当用户开始输入时,它显示了项目列表 并且用户可以从列表中 select。

<div id="formDiv">
                <Growl ref={growl}/>
                <Form className="form-column-3">
                    <div className="form-field project-name-field">
                        <label className="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-animated custom-label">Project Name</label>
                        <AutoProjects
                            fieldName='projectId'
                            value={values.projectId}
                            onChange={setFieldValue}
                            error={errors.projects}
                            touched={touched.projects}
                        />{touched.projects && errors.v && <Message severity="error" text={errors.projects}/>}
                        <Button className="add-project-btn" title="Add Project" variant="contained" color="primary"
                                type="button" onClick={props.addProject}><i className="pi pi-plus" /></Button>
                    </div>

我面临的问题是有人创建了一个新项目。基本上,自动建议列表不会在 adding/creating 个新项目之后立即显示新添加的项目。为了看到新添加的项目 在自动建议列表中,创建新项目后,用户必须点击表单的取消按钮,然后再次打开相同的表单。这样,当他们提前键入搜索他们最近的项目时,就可以看到列表 已创建。

我应该如何确保列表在他们添加项目后立即得到更新?

下面是我的 AutoProjects 组件在上面使用的样子:

import React, { Component } from 'react';

import Autosuggest from 'react-autosuggest';
import axios from "axios";
import { css } from "@emotion/core";
import ClockLoader from 'react-spinners/ClockLoader'

function escapeRegexCharacters(str) {
    return str.replace(/[.*+?^${}()|[\]\]/g, '\$&');
}

// Use your imagination to render suggestions.
const renderSuggestion = suggestion => (
    <div>
        {suggestion.name}, {suggestion.firstName}
    </div>
);

const override = css`
  display: block;
  margin: 0 auto;
  border-color: red;
`;

export class AutoProjects extends Component {
    constructor(props) {
        super(props);
        
        this.state = {
            value: '',
            projects: [],
            suggestions: [],
            loading: false
        }

        this.getSuggestionValue = this.getSuggestionValue.bind(this)
        this.setAutoSuggestValue = this.setAutoSuggestValue.bind(this)
    }

    // Teach Autosuggest how to calculate suggestions for any given input value.
    getSuggestions = value => {
        const escapedValue = escapeRegexCharacters(value.trim());

        if (escapedValue === '') {
            return [];
        }

        const regex = new RegExp(escapedValue, 'i');
        const projectData = this.state.projects;

        if (projectData) {
            return projectData.filter(per => regex.test(per.name));
        }
        else {
            return [];
        }
    };

    // When suggestion is clicked, Autosuggest needs to populate the input
    // based on the clicked suggestion. Teach Autosuggest how to calculate the
    // input value for every given suggestion.
    getSuggestionValue = suggestion => {
        this.props.onChange(this.props.fieldName, suggestion.id)//Update the parent with the new institutionId
        return suggestion.name;
    }

    fetchRecords() {
        const loggedInUser = JSON.parse(sessionStorage.getItem("loggedInUser"));
        return axios
            .get("api/projects/search/getProjectSetByUserId?value="+loggedInUser.userId)//Get all personnel
            .then(response => {
                return response.data._embedded.projects
            }).catch(err => console.log(err));
    }

    setAutoSuggestValue(response) {
        let projects = response.filter(per => this.props.value === per.id)[0]
        let projectName = '';
        if (projects) {
            projectName = projects.name
        }
        this.setState({ value: projectName})
    }

    componentDidMount() {
        this.setState({ loading: true}, () => {
            this.fetchRecords().then((response) => {
                this.setState({ projects: response, loading: false }, () => this.setAutoSuggestValue(response))
            }).catch(error => error)
        })
    }

    onChange = (event, { newValue }) => {
        this.setState({
            value: newValue
        });
    };

    // Autosuggest will call this function every time you need to update suggestions.
    // You already implemented this logic above, so just use it.
    onSuggestionsFetchRequested = ({ value }) => {
        this.setState({
            suggestions: this.getSuggestions(value)
        });
    };

    // Autosuggest will call this function every time you need to clear suggestions.
    onSuggestionsClearRequested = () => {
        this.setState({
            suggestions: []
        });
    };

    render() {
        const { value, suggestions } = this.state;

        // Autosuggest will pass through all these props to the input.
        const inputProps = {
            placeholder: value,
            value,
            onChange: this.onChange
        };

        // Finally, render it!
        return (
            <div>
                <Autosuggest
                    suggestions={suggestions}
                    onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
                    onSuggestionsClearRequested={this.onSuggestionsClearRequested}
                    getSuggestionValue={this.getSuggestionValue}
                    renderSuggestion={renderSuggestion}
                    inputProps={inputProps}
                />
                <div className="sweet-loading">
                    <ClockLoader
                        css={override}
                        size={50}
                        color={"#123abc"}
                        loading={this.state.loading}
                    />
                </div>
            </div>
        );
    }
}

问题是您仅在组件 AutoProjects 挂载时才调用 fetchRecord。这就是为什么无论何时添加新项目,列表都不会更新的原因。它仅在您关闭表单并再次打开时更新(再次安装 AutoProjects 组件) 对于这种情况,我认为您应该将 fetchProjects 的逻辑提升到父组件并将值传递给 AutoProjects。每当您添加新项目时,您需要再次调用 api 以获取新列表。