我有以下反应代码(这不是我自己的组件)。
在渲染方法中,有时this.props.src != this.state.src
我不明白为什么会这样。
我还认为state.src
是没有必要的,props.src enough
。
export default class ImageBlock extends PureComponent {
_b = _b('image')
isMount = true
state = {
src: this.props.src,
failed: false
}
componentWillMount() {
const image = new Image()
image.src = this.state.src
image.onerror = () => {
if (this.isMount) {
this.setState({ failed: true })
}
}
}
componentWillUnmount() {
this.isMount = false
}
render() {
if (this.props.src !== this.state.src) {
console.log('Sometimes this condition is true')
}
return (
<div className={ this._b({ failed: this.state.failed
}).mix(this.props.className) }>
{this.state.failed ? (
<div className={ this._b('img', { failed: true }) }>
<NoImageIcon className={ this._b('icon') } />
</div>
) : (
<img
className={
this._b('img').mix(this.props.imageClassName) }
src={ this.state.src }
alt={ this.props.title }
/>
)}
</div>
)
}
}
我如何使用此组件:
我在功能中使用它:
publisher_applications = (el, idx, index) => (
<li ref={ index } key={ idx } className={ bemCn('results-item') }>
<SearchItem
className={ bemCn('results-link', { selected: index ===
this.state.selected }) }
index={ index }
onClick={ this.handleClick }
onMouseEnter={ this.handleMouseenter }
to={{ pathname: paths.application(el.id), query: this.getQuery(el)
}}
>
<div className={ bemCn('results-image') }>
<ImageBlock
src={ setImageSize({
url: el.application.icon_url,
platform: el.platform.name.toLowerCase(),
size: 24
}) }
/>
</div>
<div className={ bemCn('results-info') }>
<div className={ bemCn('results-name') }>{el.application.name}
</div>
<div className={ bemCn('results-author') }>{el.publisher.name}
</div>
</div>
<Icon
icon={ el.platform.name.toLowerCase() === 'android' ?
googleplayIcon : appstoreIcon }
className={ bemCn('results-type') }
/>
</SearchItem>
</li>
)
在以下位置执行它:
renderResults = () => {
let index = 1
const { withoutTitle, isLanding } = this.props
return this.props.keys.map(
(key, i) => {
return (this.props.results[key] ? (
<div key={key} className={bemCn('category')}>
{!withoutTitle && <div className={bemCn('category-title')}>
{TITLES[key]}</div>}
<ul className={bemCn('results-list')}>
{this.props.results[key].slice(0,
SEARCH_RESULTS_LIMIT).map((k, idx) => {
if (isLanding && key !== 'application') return null
const item = this[key](k, idx, index)
index++
return item
})}
</ul>
</div>
) : null)
}
)
}
这里this.key
之一是方法publisher_applications.
我从服务器this.props.result
获得。