Skip to content

Commit 3b3d65f

Browse files
committed
Update documentation about AutocompleteInput and AutocompleteArrayInput
1 parent 6110ec3 commit 3b3d65f

2 files changed

Lines changed: 68 additions & 12 deletions

File tree

docs/AutocompleteArrayInput.md

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -337,25 +337,37 @@ const choices = [
337337
{ id: 123, first_name: 'Leo', last_name: 'Tolstoi' },
338338
{ id: 456, first_name: 'Jane', last_name: 'Austen' },
339339
];
340+
341+
// Note we declared the function outside the component to avoid rerenders
340342
const optionRenderer = choice => `${choice.first_name} ${choice.last_name}`;
341343

342344
<AutocompleteArrayInput source="authors" choices={choices} optionText={optionRenderer} />
343345
```
344346

345-
`optionText` also accepts a React Element, that will be rendered inside a [`<RecordContext>`](./useRecordContext.md) using the related choice as the `record` prop. You can use Field components there.
347+
**Tip**: Make sure you provide a stable reference to the function passed as `optionText`. Either declare it outside the component render function or wrap it inside a [`useCallback`](https://react.dev/reference/react/useCallback).
348+
349+
`optionText` also accepts a React Element, that will be rendered inside a [`<RecordContext>`](./useRecordContext.md) using the related choice as the `record` prop. You can use Field components there. However, using an element as `optionText` implies that you also set two more props, `inputText` and `matchSuggestion`. See [Using A Custom Element For Options](#using-a-custom-element-for-options) for more details.
350+
351+
`optionText` is also useful when the choices are records [fetched from another resource](#fetching-choices), and `<AutocompleteArrayInput>` is a child of a [`<ReferenceArrayInput>`](./ReferenceArrayInput.md).
346352

347353
```jsx
348-
const choices = [
349-
{ id: 123, first_name: 'Leo', last_name: 'Tolstoi' },
350-
{ id: 456, first_name: 'Jane', last_name: 'Austen' },
351-
];
354+
import { AutocompleteArrayInput, ReferenceArrayInput } from 'react-admin';
352355

353-
const FullNameField = () => {
354-
const record = useRecordContext();
355-
return <span>{record.first_name} {record.last_name}</span>;
356-
}
356+
<ReferenceArrayInput label="Author" source="author_id" reference="authors">
357+
<AutocompleteArrayInput />
358+
</ReferenceArrayInput>
359+
```
360+
361+
In that case, react-admin uses the [`recordRepresentation`](./Resource.md#recordrepresentation) of the related resource to display the record label. In the example above, `<AutocompleteArrayInput>` uses the resource representation of the `authors` resource, which is the `name` property.
362+
363+
But if you set the `optionText` prop, react-admin uses it instead of relying on `recordRepresentation`.
364+
365+
```jsx
366+
import { AutocompleteArrayInput, ReferenceArrayInput } from 'react-admin';
357367

358-
<AutocompleteArrayInput source="authors" choices={choices} optionText={<FullNameField />}/>
368+
<ReferenceArrayInput label="Author" source="author_id" reference="authors">
369+
<AutocompleteArrayInput optionText="last_name" />
370+
</ReferenceArrayInput>
359371
```
360372

361373
## `optionValue`
@@ -517,6 +529,7 @@ const OptionRenderer = () => {
517529
</span>
518530
);
519531
};
532+
const optionText = <OptionRenderer />;
520533
const inputText = choice => `${choice.first_name} ${choice.last_name}`;
521534
const matchSuggestion = (filter, choice) => {
522535
return (
@@ -528,12 +541,30 @@ const matchSuggestion = (filter, choice) => {
528541
<AutocompleteArrayInput
529542
source="author_ids"
530543
choices={choices}
531-
optionText={<OptionRenderer />}
544+
optionText={optionText}
532545
inputText={inputText}
533546
matchSuggestion={matchSuggestion}
534547
/>
535548
```
536549

550+
**Tip**: Make sure you pass stable references to the functions passed to the `inputText` and `matchSuggestion` by either declaring them outside the component render function or by wrapping them in a [`useCallback`](https://react.dev/reference/react/useCallback).
551+
552+
**Tip**: Make sure you pass a stable reference to the element passed to the `optionText` prop by calling it outside the component render function like so:
553+
554+
```jsx
555+
const OptionRenderer = () => {
556+
const record = useRecordContext();
557+
return (
558+
<span>
559+
<img src={record.avatar} />
560+
{record.first_name} {record.last_name}
561+
</span>
562+
);
563+
};
564+
565+
const optionText = <OptionRenderer />;
566+
```
567+
537568
## Creating New Choices
538569

539570
The `<AutocompleteArrayInput>` can allow users to create a new choice if either the `create` or `onCreate` prop is provided.

docs/AutocompleteInput.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,15 @@ const choices = [
370370
{ id: 123, first_name: 'Leo', last_name: 'Tolstoi' },
371371
{ id: 456, first_name: 'Jane', last_name: 'Austen' },
372372
];
373+
374+
// Note we declared the function outside the component to avoid rerenders
373375
const optionRenderer = choice => `${choice.first_name} ${choice.last_name}`;
376+
374377
<AutocompleteInput source="author_id" choices={choices} optionText={optionRenderer} />
375378
```
376379

380+
**Tip**: Make sure you provide a stable reference to the function passed as `optionText`. Either declare it outside the component render function or wrap it inside a [`useCallback`](https://react.dev/reference/react/useCallback).
381+
377382
`optionText` also accepts a React Element, that will be rendered inside a [`<RecordContext>`](./useRecordContext.md) using the related choice as the `record` prop. You can use Field components there. However, using an element as `optionText` implies that you also set two more props, `inputText` and `matchSuggestion`. See [Using A Custom Element For Options](#using-a-custom-element-for-options) for more details.
378383

379384
`optionText` is also useful when the choices are records [fetched from another resource](#fetching-choices), and `<AutocompleteInput>` is a child of a [`<ReferenceInput>`](./ReferenceInput.md).
@@ -637,6 +642,8 @@ const OptionRenderer = () => {
637642
</span>
638643
);
639644
};
645+
646+
const optionText = <OptionRenderer />;
640647
const inputText = choice => `${choice.first_name} ${choice.last_name}`;
641648
const matchSuggestion = (filter, choice) => {
642649
return (
@@ -648,12 +655,30 @@ const matchSuggestion = (filter, choice) => {
648655
<AutocompleteInput
649656
source="author_id"
650657
choices={choices}
651-
optionText={<OptionRenderer />}
658+
optionText={optionText}
652659
inputText={inputText}
653660
matchSuggestion={matchSuggestion}
654661
/>
655662
```
656663

664+
**Tip**: Make sure you pass stable references to the functions passed to the `inputText` and `matchSuggestion` by either declaring them outside the component render function or by wrapping them in a [`useCallback`](https://react.dev/reference/react/useCallback).
665+
666+
**Tip**: Make sure you pass a stable reference to the element passed to the `optionText` prop by calling it outside the component render function like so:
667+
668+
```jsx
669+
const OptionRenderer = () => {
670+
const record = useRecordContext();
671+
return (
672+
<span>
673+
<img src={record.avatar} />
674+
{record.first_name} {record.last_name}
675+
</span>
676+
);
677+
};
678+
679+
const optionText = <OptionRenderer />;
680+
```
681+
657682
## Creating New Choices
658683

659684
The `<AutocompleteInput>` can allow users to create a new choice if either the `create` or `onCreate` prop is provided.

0 commit comments

Comments
 (0)