列表找房模块-条件筛选
目标
- 能够设置FilterPicker组件为受控组件
- 能够获取选中值,并且设置默认选中值
获取选中值(★★★)
- 在FilterPicker组件中,添加状态value(用于获取PickerView组件的选中值)
state = {
value: null
}
- 给PickerView组件添加配置项 onChange,通过参数获取到选中值,并更新状态 value
<PickerView
data={data}
// 我们一旦监听了 onChange事件,同步了value值,那么这个组件成了受控组件,所以我们需要同步value的值
value={this.state.value}
cols={cols}
onChange={val => {
this.setState({ value: val });
}}
/>
- 在确定按钮的事件处理程序中,讲 type 和 value 作为参数传递给父组件
// Filter组件
<FilterPicker ... type={openType}/>
// FilterPicker组件
{/* 底部按钮,这个type由外界进行的传递,所以我们需要通过props来进行接收 */}
<FilterFooter onCancel={onCancel} onOk={() => onSave(type,this.state.value)} />
设置默认选中值
如果是之前选中了的,当我们再次显示FilterPicker的时候,应该展示默认选中项
- 在Filter组件中,提供选中值状态: selectedValues
// 默认选中的状态
const selectedValues = {
area: ["area", null],
mode: ["null"],
price: ["null"],
more: []
};
...
state = {
...
// 筛选默认选中的状态值
selectedValues
};
- 通过openType获取到当前类型的选中值(defaultValue),通过props传递给FilterPicker组件
const {
...,
selectedValues
} = this.state;
// 默认选中值
let defaultValue = selectedValues[openType];
...
<FilterPicker
...
defaultValue={defaultValue}
/>
- 在FilterPicker组件中,将当前defaultValue设置为状态value的默认值
state = {
value: this.props.defaultValue
}
- 在点击确定按钮后,在父组件中更新当前type对应的selectedValues状态值
// 保存,隐藏对话框
onSave = (type, value) => {
this.setState({
openType: '',
selectedValues: {
...this.state.selectedValues,
[type]: value
}
});
};
问题
- 在前面三个标签之间来回切换时候,默认选中值不会生效,当点击确定,重新打开FilterPicker组件时候,才会生效
- 分析:两种操作方式的区别在于有没有重新创建FilterPicker组件,重新创建的时候,会生效,不重新创建,不会生效
- 原因:不重新创建FilterPicker组件时,不会再次执行state初始化,也就拿不到最新的props
- 解决方式:给FilterPicker组件添加key值为openType,这样,在不同标题之间切换时候,key值都不相同,React内部会在key不同时候,重新创建该组件
列表找房模块-完善FilterTitle(★★★)
目标
- 能够说出FilterTitle高亮显示的逻辑
- 参照老师代码实现FilterTitle的高亮显示
思路
- 点击标题时,遍历标题高亮数据
- 如果是当前标题,直接设置为高亮
- 分别判断每个标题对应的筛选条件有没有选中值(判断每个筛选条件的选中值与默认值是否相同,相同表示没有选中值,不同,表示选中了值)
- selectedVal 表示当前type的选中值
- 如果type为area,此时,selectedVal.length !== 2 || selectedVal[0] !== ‘area’,就表示已经有选中值
- 如果 type 为 mode,此时,selectedVal[0] !== ‘null’,就表示已经有选中值
- 如果 type 为 price,此时,selectedVal[0] !== ‘null’,就表示有选中值
- 如果有,就让该标题保持高亮
- 如果没有,就让该标题取消高亮
实现步骤
- 在标题点击事件 onTitleClick事件里面,获取到两个状态:标题选中状态对象和筛选条件的选中值对象
const { titleSelectedStatus, selectedValues } = this.state;
- 根据当前标题选中状态对象,获取到一个新的标题选中状态对象(newTitleSelectedStatus)
// 创建新的标题选中状态对象
let newTitleSelectedStatus = { ...titleSelectedStatus };