【发布时间】:2023-04-01 09:30:02
【问题描述】:
快速而“简单”:如何让我的父组件等待某个状态被设置,直到我每次访问父组件(不仅仅是一次)渲染子组件?
更详细一点: 我希望能够根据用户输入过滤结果。我有一个控制器视图“Items”,它调用一个名为“FilterComponent”的子组件并将过滤器状态作为道具传递。我从控制器对动作创建者进行了初始调用,该动作创建者从本地存储中获取保存的过滤器并将它们分派到存储中。根据该结果,我更新过滤器状态并将其作为道具传递给孩子。
我遇到的困难是找到一种方法来确保在设置过滤器状态之前不渲染“FilterComponent”。我可以让它工作,所以当我刷新页面时,它会加载过滤器 - 但是当我在其他地方访问页面并导航到 Items 控制器时,它就会卡住。
我认为这与我通过 action/store 获取过滤器的方式有关,它在 componentDidMount() 中调用 - 因为 componentDidMount() 只调用一次,我需要每次调用它时间。
import React, { PropTypes } from 'react';
import FilterAction from '../../Actions/FilterActions';
import BaseComponent from '../../Components/Base';
import { Form, FormGroup, FormControl, ControlLabel, InputGroup, DropdownButton, MenuItem, Button } from 'react-bootstrap';
import Select from 'react-select';
import _ from 'lodash';
class FilterComponent extends BaseComponent {
constructor(props) {
super(props);
this.state = {};
this._bind(
'handleExperienceChange',
'handlePriceChange',
'applyFilter'
);
}
componentDidMount() {
this.applyFilter();
}
handlePriceChange(price) {
var filter = {};
var product = this.props.product.tag;
filter[product] = {
price: price ? price.value : null
};
let updatedState = _.merge(this.state, {
selectedPrice: price || null
});
this.updateFilter(filter);
this.setState(updatedState);
}
getPrice() {
var price = this.props.lang.select.prices;
var priceSelect = [];
Object.keys(price).map(function (key) {
priceSelect.push({
value: key,
label: price[key]
});
});
return priceSelect;
}
applyFilter() {
var filters = this.props.filters || null;
var product = this.props.product || null;
if (filters && product && filters[product.tag]) {
var selectedPrice = filter.price ? {
value: filter.price,
label: this.props.lang.select.prices[filter.price]
} : false;
}
var updatedState = {
selectedPrice: selectedPrice || false
};
this.setState(_.merge(this.state, updatedState));
}
updateFilter(filter) {
FilterAction.update(filter);
}
render() {
const { product, lang } = this.props;
return (
<div className="filter">
<div className="flex">
<div className="pane-50">
<Select name="price"
placeholder={lang.general.form.input.price}
value={this.state.selectedPrice}
options={this.getPrice()}
onChange={this.handlePriceChange}
searchable={false} />
</div>
</div>
</div>
);
}
}
export default FilterComponent;
【问题讨论】:
-
你能不能只在
Items渲染方法中检查这个状态的存在,并且如果设置了状态,只将FilterComponent作为一个孩子包含进来?喜欢(在 jsx 中){this.state.filters ? <FilterComponent {...this.state} /> : 'Loading...'} -
感谢您的回复比尔!当我在该特定页面上进行浏览器刷新时它可以工作,但是当我在其他地方进入页面并导航到项目页面时,它在“正在加载...”上没有错误。也许我的子组件是问题所在?我已经更新了我的答案并包含了我的子组件的代码。我还注意到,当我点击刷新时,它在父级中调用 render() 3 次,第三个设置了过滤器,但是当我从另一个页面导航到它时,它只渲染两次,两次过滤器未定义。
-
您的代码似乎在混合和匹配
this.props.filters和this.state.filters,这对我来说没有意义。在updateFilters中,您设置了this.state.filters,但您从未在任何地方实际使用过该状态;你在applyFilter中使用this.props.filters。这可能是你的问题吗? -
抱歉让比尔感到困惑,这个例子是我的子组件,它只依赖于
this.props.filters(见applyFilters())。updateFilters中的过滤器状态不再使用,因为我现在将任何更新的过滤器直接保存到存储中,所以请忽略该位(我已将其从上面的代码中删除)。我现在已经完全从父级中删除了 FilterComponent,它仍然停留在“正在加载...”上。我认为ChangeListener仅适用于整页重新加载。