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