我正在使用react-admin并尝试创建带有自动完成字段的过滤器,该过滤器将在我键入时进行查询,并且仅在搜索条件长度大于2时才开始发送查询。
我当前shouldRenderSuggestions在AutocompleteInput字段内部使用,但这仍然会在“昵称”过滤器中发送两个带有空字符串的请求,这是代码部分:
<AutocompleteInput optionText="nickname" shouldRenderSuggestions={(val) => {
return val.trim().length > 2
}}/>
Run Code Online (Sandbox Code Playgroud)
发生的事情是,当我填写GET发送请求的第一个和第二个字母时,但该nickname字段中有一个空字符串,
输入的字符串例如:“ abc”:
1ST要求:
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"]
3RD要求:
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>
);
};
Run Code Online (Sandbox Code Playgroud)
编辑:相同的问题<TextInput>在< Filter>字段内进行搜索,就像输入<字段一样,我开始问一个新问题,但意识到它将是重复的,
这是也从1个字符开始发送请求的代码,在这种情况下,甚至没有shouldRenderSuggestions强制它发送空请求的选项
const ClientFilter = (props) => (
<Filter {...props}>
<TextInput label="Search" source="str" alwaysOn/>
</Filter>
);
Run Code Online (Sandbox Code Playgroud)
我也偶然发现了这个问题。到目前为止,我想出的最好的方法是一个小型包装组件,ReferenceInput除非满足特定条件,否则它会阻止触发 API 请求:
const ConditionalFilter = (props) => {\n const { children, condition, setFilter } = props;\n const conditionalSetFilter = (val) => {\n if (setFilter && condition(val)) setFilter(val);\n };\n return React.cloneElement(children, { ...props, setFilter: conditionalSetFilter });\n };\nRun Code Online (Sandbox Code Playgroud)\n\n像这样使用:
\n\n const condition = val => val.trim().length > 2;\n return (\n <ReferenceInput \n source="\xe2\x80\xa6"\n reference="\xe2\x80\xa6"\n shouldRenderSuggestions={condition}\n >\n <ConditionalFilter condition={condition}>\n <AutocompleteInput />\n </ConditionalFilter>\n </ReferenceInput>\n );\nRun Code Online (Sandbox Code Playgroud)\n\nReact-admin v3 更新:没有包装器组件,不再需要/有用)
\n\nconst condition = (val) => !!val && val.trim().length > 2;\nreturn (\n <ReferenceInput\n source="\xe2\x80\xa6"\n reference="\xe2\x80\xa6"\n filterToQuery={(val) => (condition(val) ? { name: val.trim() } : {})}\n >\n <AutocompleteInput shouldRenderSuggestions={condition} />\n </ReferenceInput>\n);\nRun Code Online (Sandbox Code Playgroud)\n