Skip to content
This repository has been archived by the owner on Jul 19, 2019. It is now read-only.

Dont use deprecated lifecycle methods anymore #357

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 43 additions & 39 deletions lib/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,8 @@ class Autocomplete extends React.Component {
this.handleKeyDown = this.handleKeyDown.bind(this)
this.handleInputClick = this.handleInputClick.bind(this)
this.maybeAutoCompleteText = this.maybeAutoCompleteText.bind(this)
}

componentWillMount() {
// this.refs is frozen, so we need to assign a new object to it
this.refs = {}
// this.references is frozen, so we need to assign a new object to it
this.references = {}
this._ignoreBlur = false
this._ignoreFocus = false
this._scrollOffset = null
Expand All @@ -221,40 +218,38 @@ class Autocomplete extends React.Component {
this._scrollTimer = null
}

componentWillReceiveProps(nextProps) {
if (this.state.highlightedIndex !== null) {
this.setState(this.ensureHighlightedIndex)
}
if (nextProps.autoHighlight && (this.props.value !== nextProps.value || this.state.highlightedIndex === null)) {
this.setState(this.maybeAutoCompleteText)
}
}

componentDidMount() {
if (this.isOpen()) {
this.setMenuPositions()
}
}

componentDidUpdate(prevProps, prevState) {
let targetHighlightedIndex = this.state.highlightedIndex
if (this.state.highlightedIndex !== null) {
targetHighlightedIndex = this.ensureHighlightedIndex()
}
if (this.props.autoHighlight && (prevProps.value !== this.props.value || this.state.highlightedIndex === null)) {
targetHighlightedIndex = this.maybeAutoCompleteText()
}
if ((this.state.isOpen && !prevState.isOpen) || ('open' in this.props && this.props.open && !prevProps.open))
this.setMenuPositions()

this.maybeScrollItemIntoView()
this.maybeScrollItemIntoView(targetHighlightedIndex)
if (prevState.isOpen !== this.state.isOpen) {
this.props.onMenuVisibilityChange(this.state.isOpen)
}
}

exposeAPI(el) {
this.refs.input = el
this.references.input = el
IMPERATIVE_API.forEach(ev => this[ev] = (el && el[ev] && el[ev].bind(el)))
}

maybeScrollItemIntoView() {
if (this.isOpen() && this.state.highlightedIndex !== null) {
const itemNode = this.refs[`item-${this.state.highlightedIndex}`]
const menuNode = this.refs.menu
maybeScrollItemIntoView(highlightedIndex) {
if (this.isOpen() && highlightedIndex !== null) {
const itemNode = this.references[`item-${highlightedIndex}`]
const menuNode = this.references.menu
scrollIntoView(
findDOMNode(itemNode),
findDOMNode(menuNode),
Expand Down Expand Up @@ -334,7 +329,7 @@ class Autocomplete extends React.Component {
this.setState({
isOpen: false
}, () => {
this.refs.input.select()
this.references.input.select()
})
}
else {
Expand All @@ -346,8 +341,8 @@ class Autocomplete extends React.Component {
isOpen: false,
highlightedIndex: null
}, () => {
//this.refs.input.focus() // TODO: file issue
this.refs.input.setSelectionRange(
//this.references.input.focus() // TODO: file issue
this.references.input.setSelectionRange(
value.length,
value.length
)
Expand Down Expand Up @@ -389,37 +384,46 @@ class Autocomplete extends React.Component {
return items
}

maybeAutoCompleteText(state, props) {
const { highlightedIndex } = state
const { value, getItemValue } = props
maybeAutoCompleteText() {
const { highlightedIndex } = this.state
const { value, getItemValue } = this.props
let index = highlightedIndex === null ? 0 : highlightedIndex
let items = this.getFilteredItems(props)
let items = this.getFilteredItems(this.props)
for (let i = 0; i < items.length ; i++) {
if (props.isItemSelectable(items[index]))
if (this.props.isItemSelectable(items[index]))
break
index = (index + 1) % items.length
}
const matchedItem = items[index] && props.isItemSelectable(items[index]) ? items[index] : null
const matchedItem = items[index] && this.props.isItemSelectable(items[index]) ? items[index] : null
if (value !== '' && matchedItem) {
const itemValue = getItemValue(matchedItem)
const itemValueDoesMatch = (itemValue.toLowerCase().indexOf(
value.toLowerCase()
) === 0)
if (itemValueDoesMatch) {
return { highlightedIndex: index }
this.setState({
highlightedIndex: index
})
return index
}
}
return { highlightedIndex: null }
if(this.state.highlightedIndex !== null) {
this.setState({ highlightedIndex: null })
}
return null
}

ensureHighlightedIndex(state, props) {
if (state.highlightedIndex >= this.getFilteredItems(props).length) {
return { highlightedIndex: null }
ensureHighlightedIndex() {
if (this.state.highlightedIndex >= this.getFilteredItems(this.props).length) {
this.setState({ highlightedIndex: null })
return null
} else {
return this.state.highlightedIndex
}
}

setMenuPositions() {
const node = this.refs.input
const node = this.references.input
const rect = node.getBoundingClientRect()
const computedStyle = global.window.getComputedStyle(node)
const marginBottom = parseInt(computedStyle.marginBottom, 10) || 0
Expand Down Expand Up @@ -465,7 +469,7 @@ class Autocomplete extends React.Component {
() => this.highlightItemFromMouse(index) : null,
onClick: this.props.isItemSelectable(item) ?
() => this.selectItemFromMouse(item) : null,
ref: e => this.refs[`item-${index}`] = e,
ref: e => this.references[`item-${index}`] = e,
})
})
const style = {
Expand All @@ -475,7 +479,7 @@ class Autocomplete extends React.Component {
}
const menu = this.props.renderMenu(items, this.props.value, style)
return React.cloneElement(menu, {
ref: e => this.refs.menu = e,
ref: e => this.references.menu = e,
// Ignore blur to prevent menu from de-rendering before we can process click
onTouchStart: () => this.setIgnoreBlur(true),
onMouseEnter: () => this.setIgnoreBlur(true),
Expand All @@ -487,7 +491,7 @@ class Autocomplete extends React.Component {
if (this._ignoreBlur) {
this._ignoreFocus = true
this._scrollOffset = getScrollOffset()
this.refs.input.focus()
this.references.input.focus()
return
}
let setStateCallback
Expand Down Expand Up @@ -540,7 +544,7 @@ class Autocomplete extends React.Component {
}

isInputFocused() {
const el = this.refs.input
const el = this.references.input
return el.ownerDocument && (el === el.ownerDocument.activeElement)
}

Expand Down
25 changes: 13 additions & 12 deletions lib/__tests__/Autocomplete-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@ describe('Autocomplete acceptance tests', () => {
it('should display autocomplete menu when input has focus', () => {

expect(autocompleteWrapper.state('isOpen')).toBe(false)
expect(autocompleteWrapper.instance().refs.menu).toBe(undefined)
expect(autocompleteWrapper.instance().references.menu).toBe(undefined)

// Display autocomplete menu upon input focus
autocompleteInputWrapper.simulate('focus')

expect(autocompleteWrapper.state('isOpen')).toBe(true)
expect(autocompleteWrapper.instance().refs.menu).not.toBe(undefined)
expect(autocompleteWrapper.instance().references.menu).not.toBe(undefined)
})

it('should show results when value is a partial match', () => {

// Render autocomplete results upon partial input match
expect(autocompleteWrapper.ref('menu').children().length).toBe(50)
expect(autocompleteWrapper.instance().references.menu.children.length).toBe(50)
autocompleteWrapper.setProps({ value: 'Ar' })
expect(autocompleteWrapper.ref('menu').children().length).toBe(6)
expect(autocompleteWrapper.instance().references.menu.children.length).toBe(6)

})

Expand All @@ -58,7 +58,7 @@ describe('Autocomplete acceptance tests', () => {
autocompleteInputWrapper.simulate('blur')

expect(autocompleteWrapper.state('isOpen')).toBe(false)
expect(autocompleteWrapper.instance().refs.menu).toBe(null)
expect(autocompleteWrapper.instance().references.menu).toBe(null)

})

Expand Down Expand Up @@ -121,6 +121,7 @@ describe('Autocomplete acceptance tests', () => {

it('should reset `state.highlightedIndex` when it falls outside of possible `props.items` range', () => {
const items = getStates()
autocompleteWrapper.setProps({ value: '' })
autocompleteWrapper.setState({ highlightedIndex: 10 })
items.length = 5
autocompleteWrapper.setProps({ items })
Expand All @@ -144,7 +145,7 @@ describe('Autocomplete acceptance tests', () => {
tree.setProps({ value: 'ma' })
tree.setState({ highlightedIndex: 3 }) // Massachusetts
tree.setProps({ value: 'mas' })
expect(tree.instance().maybeAutoCompleteText).toHaveBeenCalledTimes(2)
expect(tree.instance().maybeAutoCompleteText).toHaveBeenCalledTimes(3)
expect(tree.state('highlightedIndex')).toEqual(0)
})

Expand Down Expand Up @@ -279,7 +280,7 @@ describe('focus management', () => {
const ac = tree.instance()
const input = tree.find('input')
input.simulate('focus')
ac.refs.input.focus = jest.fn(() => input.simulate('focus'))
ac.references.input.focus = jest.fn(() => input.simulate('focus'))
expect(tree.state('isOpen')).toBe(true)
const menu = tree.find('div > div').at(0)
menu.simulate('mouseEnter')
Expand All @@ -288,7 +289,7 @@ describe('focus management', () => {
expect(tree.state('isOpen')).toBe(true)
const items = tree.find('div > div > div')
items.at(3).simulate('click')
expect(ac.refs.input.focus).toHaveBeenCalledTimes(1)
expect(ac.references.input.focus).toHaveBeenCalledTimes(1)
expect(tree.state('isOpen')).toBe(false)
expect(ac._ignoreBlur).toBe(false)
})
Expand All @@ -298,7 +299,7 @@ describe('focus management', () => {
const ac = tree.instance()
const input = tree.find('input')
input.simulate('focus')
ac.refs.input.focus = jest.fn()
ac.references.input.focus = jest.fn()
expect(tree.state('isOpen')).toBe(true)
const menu = tree.find('div > div').at(0)
menu.simulate('mouseEnter')
Expand All @@ -307,7 +308,7 @@ describe('focus management', () => {
expect(tree.state('isOpen')).toBe(true)
const items = tree.find('div > div > div')
items.at(3).simulate('click')
expect(ac.refs.input.focus).toHaveBeenCalledTimes(1)
expect(ac.references.input.focus).toHaveBeenCalledTimes(1)
expect(ac._ignoreFocus).toBe(true)
input.simulate('focus')
expect(tree.state('isOpen')).toBe(false)
Expand All @@ -322,7 +323,7 @@ describe('focus management', () => {
const ac = tree.instance()
const input = tree.find('input')
input.simulate('focus')
ac.refs.input.focus = jest.fn(() => input.simulate('focus'))
ac.references.input.focus = jest.fn(() => input.simulate('focus'))
expect(tree.state('isOpen')).toBe(true)
const menu = tree.find('div > div').at(0)
menu.simulate('mouseEnter')
Expand All @@ -331,7 +332,7 @@ describe('focus management', () => {
expect(tree.state('isOpen')).toBe(true)
const nonItem = tree.find('span')
nonItem.simulate('click')
expect(ac.refs.input.focus).toHaveBeenCalledTimes(1)
expect(ac.references.input.focus).toHaveBeenCalledTimes(1)
expect(tree.state('isOpen')).toBe(true)
expect(ac._ignoreBlur).toBe(true)
})
Expand Down