如题,每次点击input的时候才能输入一次
查看了代码,原因应该是当我每次输入触发onChange的时候DOM重绘,但是根源并不清楚到底是什么,望指教;
因为是第一次用react,所以有什么问题大家也可以提出来,让我改进一下,谢谢!
代码如下
class Goods extends Component {
constructor() {
super();
this.state = {
id: '',
name: '',
orderBy_id: 3,// 排序
isFilter: false,
type: '',//类型
page_num: 1, // 页码
min_price: '', // 最低价
max_price: '', // 最高价
screen_id: '', // 筛选选择类型
str: ''
};
this.changeSort = this.changeSort.bind(this);
this.changeProd = this.changeProd.bind(this);
this.selectedAttr = this.selectedAttr.bind(this);
this.resetAttr = this.resetAttr.bind(this);
this.selectedFilter = this.selectedFilter.bind(this);
this.changePrice = this.changePrice.bind(this);
this.closeModal = this.closeModal.bind(this);
}
changePrice(event) {
const target = event.target;
if(target.name === 'min_price') {
this.setState({
min_price: event.target.value
})
}else {
this.setState({
max_price: event.target.value
})
}
}
render() {
const {data} = this.props;
const SelectWrapper = () => {
return (
<TopWrapper>
<TopItem className={(this.state.orderBy_id === 3 && !this.state.isFilter) ? 'selected' : ''}
onClick={(e) => this.changeSort(e, 'other', 3)}>
<span className='text'>综合</span>
</TopItem>
<TopItem className={(this.state.orderBy_id === 5 && !this.state.isFilter) ? 'selected' : ''}
onClick={(e) => this.changeSort(e, 'other', 5)}>
<span className='text'>销量</span>
</TopItem>
<TopItem
className={((this.state.orderBy_id === 2 || this.state.orderBy_id === 1) && !this.state.isFilter) ? 'selected' : ''}
onClick={(e) => this.changeSort(e, 'price')}>
<span className='text'>价格</span>
<span className='icon'>
<i className={`iconfont icon-shangjiantou ${this.state.orderBy_id === 2 ? 'selected' : ''}`}></i>
<br/>
<i className={`iconfont icon-xiajiantou ${this.state.orderBy_id === 1 ? 'selected' : ''}`}></i>
</span>
</TopItem>
<TopItem className={this.state.isFilter ? 'selected' : ''}
onClick={(e) => this.changeSort(e, 'shaixuan')}>
<span className='text'>筛选</span>
<span className='icon'>
<i className='iconfont'></i>
<br/>
<i className={`iconfont icon-xiajiantou ${this.state.isFilter ? 'selected' : ''}`}></i>
</span>
</TopItem>
</TopWrapper>
)
};
const ProductContainers = () => {
let isSelf = (type) => {
if(type === '1') {
return (
<span>自营</span>
)
}
return null;
};
if(!data.length){
return null
}
return (
<ProductWrapper>{
data.map((item, index) => {
return (
<ProductItem key={index}>
<div className='img'>
<img src={item.image} alt=""/>
</div>
<p className='name'>
{
isSelf(item.support_type)
}
{item.name}
</p>
<p className='price'>¥
<span>
{(item.price).toFixed(2)}
</span>
</p>
</ProductItem>
)
})
}
</ProductWrapper>
)
};
const FilterContainer = () => {
const {isFilter, screen_id, min_price, max_price} = this.state;
const {options} = this.props;
if(isFilter) {
return (
<FilterWrapper>
<div className='content'>
<p className='title'>聚鲨服务</p>
<ul>
{
options.map((item, index) => {
if(screen_id.indexOf(item.id) > -1) {
return (
<li key={index} onClick={() => {this.selectedAttr(item.id)}} className='screen-select'>{item.name}
<img className='selected' src='http://wp.ghs.net/static/img/selectBg.png' alt=""/>
</li>
)
}else {
return (
<li key={index} onClick={() => {this.selectedAttr(item.id)}}>{item.name}</li>
)
}
})
}
</ul>
<p className='title'>价格区间</p>
<p className='price-range'>
<input type="text" name='min_price' placeholder='最低价' onChange={this.changePrice} value={min_price} />
<span>-</span>
<input type="text" name='max_price' placeholder='最高价' onChange={this.changePrice} value={max_price}/>
</p>
<div className='buttons'>
<p className='reset' onClick={this.resetAttr}>重置条件</p>
<p className='sure' onClick={this.selectedFilter}>确定</p>
</div>
</div>
<div className='model' onClick={this.closeModal}></div>
</FilterWrapper>
)
}
return null
};
return (
<Wrapper>
<SelectWrapper/>
<FilterContainer />
<ProductContainers/>
</Wrapper>
)
}
}
应该是在循环中的
key
值使用了index
的缘故吧。由于
React
中的diff
算法需要通过key
值判断前后的虚拟dom
是否发生了改变,加上index
的值会动态改变的缘故,所以会导致dom
重绘。之前,我在循环中产生了包含
input
的dom
结构,并使用了时间戳作为key
值出现了同样的情况。任何情况下建议给
key
一个固定唯一的值。I hope this will help you.