如果react-admin中查询字段的长度很短,如何防止发送get请求

How to prevent get request from being send if the length of the query field is short in react-admin

我正在使用 react-admin 并尝试创建一个带有自动完成字段的过滤器,它将在我键入时进行查询,并且只会在搜索条件长度超过 2 时才开始发送查询。

我目前在我的 AutocompleteInput 字段中使用 shouldRenderSuggestions 但这仍然会在 "nickname" 过滤器中发送两个带有空字符串的请求,这是代码部分:

<AutocompleteInput optionText="nickname" shouldRenderSuggestions={(val) => {
        return val.trim().length > 2
      }}/>

发生的事情是,当我填写第一个和第二个字母时,GET 请求已发送,但 nickname 字段中的字符串为空,

字符串输入例如:"abc":

第一个请求: http://website.loc/clients?filter={"nickname":""}&page=1&perPage=25&range=[0,24]&sort=["id","DESC"]

第二次请求: http://website.loc/clients?filter={"nickname":""}&page=1&perPage=25&range=[0,24]&sort=["id","DESC"]

第三次请求: http://website.loc/clients?filter={"nickname":"abc"}&page=1&perPage=25&range=[0,24]&sort=["id","DESC"]

我想避免完全发送前两个请求。

组件完整代码:

const PostPagination = props => (
  <Pagination rowsPerPageOptions={[]} {...props} />
);

const PostFilter = (props) => (
  <Filter {...props}>
    <ReferenceInput label="Client"
                    source="client_id"
                    reference="clients"
                    allowEmpty
                    filterToQuery={searchText => ({ nickname: searchText })}>
      <AutocompleteInput optionText="nickname" shouldRenderSuggestions={(val) => {
        return val.trim().length > 2
      }}/>
    </ReferenceInput>
  </Filter>
);

const PostsList = props => {
  return (
    <List {...props} perPage={15}
          pagination={<PostPagination/>}
          filters={<PostFilter/>}
          exporter={false}>
      <Datagrid>
        <TextField source="nickname" sortable={false}/>
        <DateField label="Created" source="created_at" showTime/>
      </Datagrid>
    </List>
  );
};

编辑: 同样的问题也适用于 "search-as-you-type" 字段,例如 <Filter> 字段中的 <TextInput>,我开始问一个新问题但意识到它会有点重复,

这也是从 1 个字符开始发送请求的代码,在这种情况下甚至没有 shouldRenderSuggestions 选项来强制它发送空请求

const ClientFilter = (props) => (
  <Filter {...props}>
    <TextInput label="Search" source="str" alwaysOn/>
  </Filter>
);

Live example of code in codesandbox.io

我也偶然发现了这个问题。到目前为止我想出的最好的是一个小的包装器组件,它可以防止 ReferenceInput 触发 API 请求,除非满足特定条件:

  const ConditionalFilter = (props) => {
    const { children, condition, setFilter } = props;
    const conditionalSetFilter = (val) => {
      if (setFilter && condition(val)) setFilter(val);
    };
    return React.cloneElement(children, { ...props, setFilter: conditionalSetFilter });
  };

这样使用:

  const condition = val => val.trim().length > 2;
  return (
    <ReferenceInput 
      source="…"
      reference="…"
      shouldRenderSuggestions={condition}
    >
      <ConditionalFilter condition={condition}>
        <AutocompleteInput />
      </ConditionalFilter>
    </ReferenceInput>
  );

react-admin v3 的更新:(没有包装器组件,不再是 necessary/useful)

const condition = (val) => !!val && val.trim().length > 2;
return (
  <ReferenceInput
    source="…"
    reference="…"
    filterToQuery={(val) => (condition(val) ? { name: val.trim() } : {})}
  >
    <AutocompleteInput shouldRenderSuggestions={condition} />
  </ReferenceInput>
);