reactjs - React.js - 使用不同设置多次使用一个组件
问题描述
我正在尝试创建一个可重用的组件,该组件包含类似的功能,其中唯一更改的是标题字符串和用于填充 Kendo ComboBox 的数据。
因此,我有一个导航菜单(目前)加载了六个不同的过滤器:
{
context && context.Filters && context.Filters.map((item) => getComponent(item))
}
GetComponent 获取过滤器的 ID,从上下文中获取过滤器的定义,并创建一个下拉组件传入属性:
function getComponent(item) {
var filterDefinition = context.Filters.find(filter => filter.Id === item.Id);
switch (item.DisplayType) {
case 'ComboBox':
return <DropDownFilterable key={item.Id} Id={item.Id} Definition={filterDefinition} />
default:
return null;
}
}
DropDownFilterable 组件调用服务来获取组合框的数据,然后加载所有内容:
const DropDownFilterable = (props) => {
const appService = Service();
filterDefinition = props.Definition;
console.log(filterDefinition.Name + " - " + filterDefinition.Id);
React.useEffect(() => {
console.log("useEffect: " + filterDefinition.Name + " - " + filterDefinition.Id);
appService.getFilterValues(filterDefinition.Id).then(response => {
filterData = response;
})
}, []);
return (
<div>
<div className="row" title={filterDefinition.DisplayName}>{filterDefinition.DisplayName}</div>
<ComboBox
id={"filterComboBox_" + filterDefinition.Id}
data={filterData}
//onOpen={console.log("test")}
style={{zIndex: 999999}}
dataItemKey={filterDefinition && filterDefinition.Definition && filterDefinition.Definition.DataHeaders[0]}
textField={filterDefinition && filterDefinition.Definition && filterDefinition.Definition.DataHeaders[1]}
/>
</div>
)
}
服务电话:
function getFilterValues(id) {
switch(id) {
case "E903B2D2-55DE-4FA3-986A-8A038751C5CD":
return fetch(Settings.url_getCurrencies).then(toJson);
default:
return fetch(Settings.url_getRevenueScenarios).then(toJson);
}
};
发生的情况是,每个过滤器的标题 (DisplayName) 都正确呈现在导航菜单上,但所有六个过滤器的数据都是最后传入的过滤器的数据。我是 React 的新手,我对钩子还不是 100% 满意,所以我可能以错误的顺序做某事,或者没有在正确的钩子中做某事。我创建了一个精简版的应用程序:
https://codesandbox.io/s/spotlight-react-full-forked-r25ns
任何帮助,将不胜感激。谢谢!
解决方案
这是因为您使用filterData
不正确 - 您在组件之外定义了它,DropDownFilterable
这意味着它将被共享。相反,将值设置为组件状态(我已缩短代码以仅包含我的更改):
const DropDownFilterable = (props) => {
// ...
// store filterData in component state
const [filterData, setFilterData] = React.useState(null);
React.useEffect(() => {
// ...
appService.getFilterValues(filterDefinition.Id).then(response => {
// update filterData with response from appService
setFilterData(response);
})
}, []);
// only show a ComboBox if filterData is defined
return filterData && (
// ...
)
}
或者,您可以使用空数组作为默认状态...
const [filterData, setFilterData] = React.useState([]);
...因为ComboBox
组件接受data
道具的数组。这样你就不必有条件地渲染。
更新
因为filterDefinition
您还需要确保它设置正确:
const [filterDefinition, setFilterDefinition] = React.useState(props.Definition);
// ...
React.useEffect(() => {
setFilterDefinition(props.Definition);
}, [props.Definition]);
filterDefinition
如果您不希望它改变,那么保持状态也可能更容易:
const filterDefinition = props.Definition || {};
推荐阅读
- javascript - 对讲机(客户端)JavaScript“消息发送”回调/事件?
- spring - 提取访问令牌
- javascript - 当我不知道文档 ID 时如何使用 mongoose 查询子文档
- r - ggplot:直方图的透明度作为统计(计数)的函数
- go - vscode如何停止发送错误通知?
- python - 无法升级 pip 和请求模块
- javascript - 控制台记录数组中的对象出现的次数,无论其中的字符大小写如何
- python - 控制台中文件夹目录的Python实现
- php - 检测重复数组,然后在 PHP 中将插入推送到新数组
- c++ - GLUT displayfunc 在没有回调设置的事件中调用