Skip to content

Commit

Permalink
feat(id): add id prop for improved SSR (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kent C. Dodds authored Sep 23, 2017
1 parent 1c952ff commit 47a20ae
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ harder to contribute to.
- [Control Props](#control-props)
- [Child Callback Function](#child-callback-function)
- [Examples](#examples)
- [FAQ](#faq)
- [Inspiration](#inspiration)
- [Other Solutions](#other-solutions)
- [Contributors](#contributors)
Expand Down Expand Up @@ -287,6 +288,14 @@ The currently selected item.
This is called with an object. Read more about the properties of this object
in the section "Child Callback Function"

### id

> `string` | defaults to a generated ID
You should not normally need to set this prop. It's only useful if you're
server rendering items (which each have an `id` prop generated based on the
`downshift` `id`). For more information see the `FAQ` below.

## Control Props

downshift manages its own state internally and calls your `onChange` and
Expand Down Expand Up @@ -517,6 +526,36 @@ You'll find other examples in the `stories/examples` folder of the repo.
And you'll find
[a live version of those examples here](https://downshift.netlify.com)

## FAQ

<details>

<summary>How do I avoid the checksum error when server rendering (SSR)?</summary>

The checksum error you're seeing is most likely due to the automatically
generated `id` and/or `htmlFor` prop you get from `getInputProps` and
`getLabelProps` (respectively). It could also be from the automatically
generated `id` prop you get from `getItemProps` (though this is not likely as
you're probably not rendering any items when rendering a downshift component
on the server).

To avoid these problems, simply provide your own `id` prop in `getInputProps`
and `getLabelProps`. Also, you can use the `id` prop on the component
`Downshift`. For example:

```javascript
<Downshift id="autocomplete">
{({getInputProps, getLabelProps}) => (
<label {...getLabelProps({htmlFor: 'autocomplete-input'})}>
Some Label
</label>
<input {...getInputProps({id: 'autocomplete-input'})} />
)}
</Downshift>
```

</details>


## Inspiration

Expand Down
6 changes: 6 additions & 0 deletions src/__tests__/downshift.misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ test('openAndHighlightDefaultIndex can take no arguments at all', () => {
)
})

test('can specify a custom ID which is used in item IDs (good for SSR)', () => {
const id = 'my-custom-id'
const {getItemProps} = setup({id})
expect(getItemProps({item: 'blah'}).id).toContain(id)
})

function setup({children = () => <div />, ...props} = {}) {
let renderArg
const childSpy = jest.fn(controllerArg => {
Expand Down
5 changes: 3 additions & 2 deletions src/downshift.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Downshift extends Component {
onUserAction: PropTypes.func,
onClick: PropTypes.func,
itemCount: PropTypes.number,
id: PropTypes.string,
// things we keep in state for uncontrolled components
// but can accept as props for controlled components
/* eslint-disable react/no-unused-prop-types */
Expand All @@ -49,6 +50,7 @@ class Downshift extends Component {
defaultInputValue: '',
defaultIsOpen: false,
getA11yStatusMessage,
id: generateId('downshift'),
itemToString: i => (i == null ? '' : String(i)),
onStateChange: () => {},
onUserAction: () => {},
Expand Down Expand Up @@ -93,7 +95,6 @@ class Downshift extends Component {
this.state = state
}

id = generateId('downshift')
root_handleClick = composeEventHandlers(
this.props.onClick,
this.root_handleClick,
Expand Down Expand Up @@ -543,7 +544,7 @@ class Downshift extends Component {

/////////////////////////////// ITEM
getItemId(index) {
return `${this.id}-item-${index}`
return `${this.props.id}-item-${index}`
}

getItemProps = (
Expand Down

0 comments on commit 47a20ae

Please sign in to comment.