Merge pull request #125 from Gargron/fix-useless-rerenders
Remove function binds in render wherever possible, use PureComponentnolan/hinaloe-test
commit
bbd4fbe764
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
|||
|
||||
import SVGs from '../svgs'
|
||||
|
||||
export default class Anchors extends React.Component {
|
||||
export default class Anchors extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
|
@ -14,6 +14,15 @@ export default class Anchors extends React.Component {
|
|||
this.state = {
|
||||
selected: defaultCategory.name
|
||||
}
|
||||
|
||||
this.handleClick = this.handleClick.bind(this)
|
||||
}
|
||||
|
||||
handleClick (e) {
|
||||
var index = e.currentTarget.getAttribute('data-index')
|
||||
var { categories, onAnchorClick } = this.props
|
||||
|
||||
onAnchorClick(categories[index], index)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -33,7 +42,8 @@ export default class Anchors extends React.Component {
|
|||
<span
|
||||
key={name}
|
||||
title={i18n.categories[name.toLowerCase()]}
|
||||
onClick={() => onAnchorClick(category, i)}
|
||||
data-index={i}
|
||||
onClick={this.handleClick}
|
||||
className={`emoji-mart-anchor ${isSelected ? 'emoji-mart-anchor-selected' : ''}`}
|
||||
style={{ color: isSelected ? color : null }}
|
||||
>
|
||||
|
|
|
@ -5,6 +5,13 @@ import frequently from '../utils/frequently'
|
|||
import { Emoji } from '.'
|
||||
|
||||
export default class Category extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.setContainerRef = this.setContainerRef.bind(this)
|
||||
this.setLabelRef = this.setLabelRef.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.parent = this.container.parentNode
|
||||
|
||||
|
@ -133,16 +140,13 @@ export default class Category extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
return <div ref={this.setContainerRef.bind(this)} className={`emoji-mart-category ${emojis && !emojis.length ? 'emoji-mart-no-results' : ''}`} style={containerStyles}>
|
||||
return <div ref={this.setContainerRef} className={`emoji-mart-category ${emojis && !emojis.length ? 'emoji-mart-no-results' : ''}`} style={containerStyles}>
|
||||
<div style={labelStyles} data-name={name} className='emoji-mart-category-label'>
|
||||
<span style={labelSpanStyles} ref={this.setLabelRef.bind(this)}>{i18n.categories[name.toLowerCase()]}</span>
|
||||
<span style={labelSpanStyles} ref={this.setLabelRef}>{i18n.categories[name.toLowerCase()]}</span>
|
||||
</div>
|
||||
|
||||
{emojis && emojis.map((emoji) =>
|
||||
Emoji({
|
||||
emoji: emoji,
|
||||
...emojiProps
|
||||
})
|
||||
Emoji({ emoji: emoji, ...emojiProps })
|
||||
)}
|
||||
|
||||
{emojis && !emojis.length &&
|
||||
|
|
|
@ -32,7 +32,7 @@ const I18N = {
|
|||
},
|
||||
}
|
||||
|
||||
export default class Picker extends React.Component {
|
||||
export default class Picker extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
|
@ -115,6 +115,19 @@ export default class Picker extends React.Component {
|
|||
}
|
||||
|
||||
this.categories.unshift(SEARCH_CATEGORY)
|
||||
|
||||
this.setAnchorsRef = this.setAnchorsRef.bind(this)
|
||||
this.handleAnchorClick = this.handleAnchorClick.bind(this)
|
||||
this.setSearchRef = this.setSearchRef.bind(this)
|
||||
this.handleSearch = this.handleSearch.bind(this)
|
||||
this.setScrollRef = this.setScrollRef.bind(this)
|
||||
this.handleScroll = this.handleScroll.bind(this)
|
||||
this.handleScrollPaint = this.handleScrollPaint.bind(this)
|
||||
this.handleEmojiOver = this.handleEmojiOver.bind(this)
|
||||
this.handleEmojiLeave = this.handleEmojiLeave.bind(this)
|
||||
this.handleEmojiClick = this.handleEmojiClick.bind(this)
|
||||
this.setPreviewRef = this.setPreviewRef.bind(this)
|
||||
this.handleSkinChange = this.handleSkinChange.bind(this)
|
||||
}
|
||||
|
||||
componentWillReceiveProps(props) {
|
||||
|
@ -206,7 +219,7 @@ export default class Picker extends React.Component {
|
|||
handleScroll() {
|
||||
if (!this.waitingForPaint) {
|
||||
this.waitingForPaint = true
|
||||
window.requestAnimationFrame(this.handleScrollPaint.bind(this))
|
||||
window.requestAnimationFrame(this.handleScrollPaint)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,17 +381,17 @@ export default class Picker extends React.Component {
|
|||
return <div style={{width: width, ...style}} className='emoji-mart'>
|
||||
<div className='emoji-mart-bar'>
|
||||
<Anchors
|
||||
ref={this.setAnchorsRef.bind(this)}
|
||||
ref={this.setAnchorsRef}
|
||||
i18n={this.i18n}
|
||||
color={color}
|
||||
categories={this.categories}
|
||||
onAnchorClick={this.handleAnchorClick.bind(this)}
|
||||
onAnchorClick={this.handleAnchorClick}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Search
|
||||
ref={this.setSearchRef.bind(this)}
|
||||
onSearch={this.handleSearch.bind(this)}
|
||||
ref={this.setSearchRef}
|
||||
onSearch={this.handleSearch}
|
||||
i18n={this.i18n}
|
||||
emojisToShowFilter={emojisToShowFilter}
|
||||
include={include}
|
||||
|
@ -387,7 +400,7 @@ export default class Picker extends React.Component {
|
|||
autoFocus={autoFocus}
|
||||
/>
|
||||
|
||||
<div ref={this.setScrollRef.bind(this)} className='emoji-mart-scroll' onScroll={this.handleScroll.bind(this)}>
|
||||
<div ref={this.setScrollRef} className='emoji-mart-scroll' onScroll={this.handleScroll}>
|
||||
{this.getCategories().map((category, i) => {
|
||||
return <Category
|
||||
ref={this.setCategoryRef.bind(this, `category-${i}`)}
|
||||
|
@ -407,9 +420,9 @@ export default class Picker extends React.Component {
|
|||
sheetSize: sheetSize,
|
||||
forceSize: native,
|
||||
backgroundImageFn: backgroundImageFn,
|
||||
onOver: this.handleEmojiOver.bind(this),
|
||||
onLeave: this.handleEmojiLeave.bind(this),
|
||||
onClick: this.handleEmojiClick.bind(this),
|
||||
onOver: this.handleEmojiOver,
|
||||
onLeave: this.handleEmojiLeave,
|
||||
onClick: this.handleEmojiClick,
|
||||
}}
|
||||
/>
|
||||
})}
|
||||
|
@ -417,7 +430,7 @@ export default class Picker extends React.Component {
|
|||
|
||||
{showPreview && <div className='emoji-mart-bar'>
|
||||
<Preview
|
||||
ref={this.setPreviewRef.bind(this)}
|
||||
ref={this.setPreviewRef}
|
||||
title={title}
|
||||
emoji={emoji}
|
||||
emojiProps={{
|
||||
|
@ -430,7 +443,7 @@ export default class Picker extends React.Component {
|
|||
}}
|
||||
skinsProps={{
|
||||
skin: skin,
|
||||
onChange: this.handleSkinChange.bind(this)
|
||||
onChange: this.handleSkinChange
|
||||
}}
|
||||
/>
|
||||
</div>}
|
||||
|
|
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
|
|||
import { Emoji, Skins } from '.'
|
||||
import { getData } from '../utils'
|
||||
|
||||
export default class Preview extends React.Component {
|
||||
export default class Preview extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { emoji: null }
|
||||
|
@ -31,11 +31,7 @@ export default class Preview extends React.Component {
|
|||
|
||||
return <div className='emoji-mart-preview'>
|
||||
<div className='emoji-mart-preview-emoji'>
|
||||
{Emoji({
|
||||
key: emoji.id,
|
||||
emoji: emoji,
|
||||
...emojiProps,
|
||||
})}
|
||||
{Emoji({ key: emoji.id, emoji: emoji, ...emojiProps })}
|
||||
</div>
|
||||
|
||||
<div className='emoji-mart-preview-data'>
|
||||
|
@ -55,10 +51,7 @@ export default class Preview extends React.Component {
|
|||
} else {
|
||||
return <div className='emoji-mart-preview'>
|
||||
<div className='emoji-mart-preview-emoji'>
|
||||
{idleEmoji && idleEmoji.length && Emoji({
|
||||
emoji: idleEmoji,
|
||||
...emojiProps,
|
||||
})}
|
||||
{idleEmoji && idleEmoji.length && Emoji({ emoji: idleEmoji, ...emojiProps })}
|
||||
</div>
|
||||
|
||||
<div className='emoji-mart-preview-data'>
|
||||
|
|
|
@ -2,7 +2,14 @@ import React from 'react'
|
|||
import PropTypes from 'prop-types'
|
||||
import emojiIndex from '../utils/emoji-index'
|
||||
|
||||
export default class Search extends React.Component {
|
||||
export default class Search extends React.PureComponent {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.setRef = this.setRef.bind(this)
|
||||
this.handleChange = this.handleChange.bind(this)
|
||||
}
|
||||
|
||||
handleChange() {
|
||||
var value = this.input.value
|
||||
|
||||
|
@ -28,9 +35,9 @@ export default class Search extends React.Component {
|
|||
|
||||
return <div className='emoji-mart-search'>
|
||||
<input
|
||||
ref={this.setRef.bind(this)}
|
||||
ref={this.setRef}
|
||||
type='text'
|
||||
onChange={this.handleChange.bind(this)}
|
||||
onChange={this.handleChange}
|
||||
placeholder={i18n.search}
|
||||
autoFocus={autoFocus}
|
||||
/>
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default class Skins extends React.Component {
|
||||
export default class Skins extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
opened: false,
|
||||
}
|
||||
|
||||
this.handleClick = this.handleClick.bind(this)
|
||||
}
|
||||
|
||||
handleClick(skin) {
|
||||
handleClick(e) {
|
||||
var skin = e.currentTarget.getAttribute('data-skin')
|
||||
var { onChange } = this.props
|
||||
|
||||
if (!this.state.opened) {
|
||||
|
@ -39,9 +42,9 @@ export default class Skins extends React.Component {
|
|||
className={`emoji-mart-skin-swatch ${selected ? 'emoji-mart-skin-swatch-selected' : ''}`}
|
||||
>
|
||||
<span
|
||||
onClick={() => this.handleClick(skinTone)}
|
||||
className={`emoji-mart-skin emoji-mart-skin-tone-${skinTone}`}>
|
||||
</span>
|
||||
onClick={this.handleClick}
|
||||
data-skin={skinTone}
|
||||
className={`emoji-mart-skin emoji-mart-skin-tone-${skinTone}`} />
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue