我有一个主要组件如下:
render() {
const language = this.props.language.default.portal;
return (
<div>
<div className="searchLeft noPadding col-xl-2 col-lg-2 col-md-2 col-sm-3 col-xs-5">
<Price language={language} actionFilters={this.props.actionFilters} allCarsInTheList={this.props.carsToShow}/>
</div>
<div className="contentRight noPadding col-xl-10 col-lg-10 col-md-10 col-sm-9 col-xs-7">
<div className="filterBar">
<SmallFilters language={language} filters={this.props.filters} allCarsInTheList={this.props.carsToShow} actionFilters={this.props.actionFilters}/>
</div>
</div>
</div>
);
}
我的价格成分如下:
export default class PriceRangeFilter extends React.Component {
constructor(props) {
super(props);
this.state = {
range: {
low: _.min(this.props.allCarsInTheList.map (i => i.price)),
high: _.max(this.props.allCarsInTheList.map (i => i.price)),
active: false
}
};
}
handleFilter(){
if(this.state.range.active){
this.props.actionFilters.addPriceRangeFilter(this.state.range);
}else{
this.props.actionFilters.removePriceRangeFilter();
}
}
changeFilter(range) {
this.setState({range: range}, this.handleFilter);
}
deActivate(event) {
event.preventDefault();
let n_range = this.state.range;
n_range.active = false;
this.changeFilter(n_range);
}
renderSmall() {
return (
<div key={this.props.key} className="filter">
{this.props.title} <Link to="" onClick={this.deActivate.bind(this)}><FontAwesome name="times" className="portalFaRedIcon"/></Link>
</div>
);
}
render(){
const language = this.props.language;
if(this.props.recap) return this.renderSmall();
console.log(this.state.range);
return (
<div>
<div className="priceTitle">{language.price}</div>
<SliderRange language={language}
range={this.state.range}
min={_.min(this.props.allCarsInTheList.map (i => i.price))}
max={_.max(this.props.allCarsInTheList.map (i => i.price))}
step={data.configuration.PRICE_RANGE_STEP}
sign="€"
type="price"
onChange={this.changeFilter.bind(this)} />
</div>
);
}
}
我的SmallFilters组件如下:
import PriceFilter from './price';
class filters extends React.Component {
checkFilter(name, filters){
return filters.some(f => name == f.name);
}
showFilter(filters){
if(this.checkFilter(filter_names.priceRange, filters)){
return <PriceFilter recap={this.checkFilter(filter_names.priceRange, filters)} title="Price" allCarsInTheList={this.props.allCarsInTheList} actionFilters={this.props.actionFilters}/>
}
}
render(){
const language = this.props.language;
const filters = this.props.filters;
return (
<div className="filters noPadding col-xl-8 col-lg-6 col-md-6 col-sm-5 col-xs-12">
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true} transitionAppearTimeout={500} transitionEnterTimeout={500} transitionLeaveTimeout={500}>
{this.showFilter(filters)}
</ReactCSSTransitionGroup>
</div>
);
}
}
问题出在SmallFilters组件中。我在那里包含与搜索组件中相同的Price组件。然后,在价格组件中,如果renderSmall
为真,则返回this.props.recap
函数。
当我点击renderSmall
内的链接停用过滤器时,它应该更新状态。但是国家没有改变。 this.state.range.active
保持正确。
有什么建议吗?
更新
SliderRange组件代码如下:
import React, {PropTypes} from 'react';
import {formatNumber} from './formatNumber';
export default class SliderRange extends React.Component {
constructor(props) {
super(props);
this.state = this.getStateFromProps(this.props);
}
componentWillReceiveProps(newProps){
this.setState(this.getStateFromProps(newProps));
}
getStateFromProps(props) {
return {
low: props.range.low,
high: props.range.high,
active: props.range.active
};
}
numberWithSpace(number) {
return (this.props.type == "year") ? number : formatNumber(number);
}
handleChange(low, high, active) {
let n_active = active;
if(low!=this.state.low) n_active = true;
if(high!=this.state.high) n_active = true;
if(low == this.props.min && high == this.props.max) n_active = false;
const result = {
low: low,
high: high,
active: n_active
};
this.props.onChange(result);
}
handleActive(event) {
const checkbox = event.target.checked;
let low = this.state.low;
let high = this.state.high;
if(checkbox && this.state.low == this.props.min && this.state.high == this.props.max) {
low = this.props.min + this.props.step;
high = this.props.max - this.props.step;
}else{
low = this.props.min;
high = this.props.max;
}
this.handleChange(low, high, checkbox);
}
handleLow(event) {
if(parseInt(event.target.value) < parseInt(this.state.high)){
this.handleChange(event.target.value, this.state.high, this.state.active);
}
}
handleHigh(event) {
if(parseInt(event.target.value) > parseInt(this.state.low)) {
this.handleChange(this.state.low, event.target.value, this.state.active);
}
}
render() {
const sign = this.props.sign;
const min = this.props.min;
const max = this.props.max;
const step = this.props.step;
const low = this.state.low;
const high = this.state.high;
const active = this.state.active;
return (
<div>
<div className="rangeValues">Range : {this.numberWithSpace(low)} {sign} - {this.numberWithSpace(high)} {sign}</div>
<section className="range-slider">
<input type="checkbox" checked={active} onChange={this.handleActive.bind(this)}/>
<input type="range" name="first" value={low} min={min} max={max} step={step} onChange={this.handleLow.bind(this)} className="firstRange"/>
<input type="range" name="second" value={high} min={min} max={max} step={step} onChange={this.handleHigh.bind(this)} className="secondRange"/>
<div className="minValue">{this.numberWithSpace(min)} {sign}</div>
<div className="maxValue">{this.numberWithSpace(max)} {sign}</div>
</section>
</div>
);
}
}
SliderRange.propTypes = {
language: PropTypes.object.isRequired,
range: PropTypes.object.isRequired,
min: PropTypes.number.isRequired,
max: PropTypes.number.isRequired,
step: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired
};
答案 0 :(得分:0)
您正在更改嵌套属性。尝试使用Object.assign()创建一个新对象,如下所示:
deActivate(event) {
event.preventDefault();
let n_range = Object.assign({}, this.state.range);
n_range.active = false;
this.changeFilter(n_range);
}