【发布时间】:2019-11-03 19:01:59
【问题描述】:
我有一个对象列表,我想传递给 map 函数,该函数将每个对象作为道具传递给要渲染的组件。
我有一个菜单,单击每个项目调用 setActiveItem() 更新由 useState 挂钩管理的 activeItem。
我正在尝试根据这个 activeItem 值过滤对象列表。我已经创建了一个试图复制问题的基本案例,但我的基本案例完美无缺,尽管它至少可以阐明我正在尝试这样做:
import React, { useState } from 'react';
import { Menu } from 'semantic-ui-react';
const [ALL, NUMBER, LETTER] = ['All', 'Number', 'Letter'];
const data = [
{
tags: [ALL, NUMBER],
value: '1'
},
{
tags: [ALL, LETTER],
value: 'a'
},
{
tags: [ALL, NUMBER],
value: '2'
},
{
tags: [ALL, LETTER],
value: 'b'
},
{
tags: [ALL, NUMBER],
value: '3'
},
{
tags: [ALL, LETTER],
value: 'c'
},
{
tags: [ALL, NUMBER],
value: '4'
},
{
tags: [ALL, LETTER],
value: 'd'
}
];
const renderData = (allValues, filterTag) => {
let filteredList = allValues.filter(val => {
return val['tags'].includes(filterTag);
});
return (
<div>
{filteredList.map(object_ => {
return object_.value;
})}
</div>
);
};
const BaseCase = props => {
const [activeItem, setActiveItem] = useState(ALL);
return (
<div>
<Menu inverted stackable fluid widths={4}>
<Menu.Item
name={ALL}
active={activeItem === ALL}
onClick={(e, { name }) => setActiveItem(name)}
/>
<Menu.Item
name={NUMBER}
active={activeItem === NUMBER}
onClick={(e, { name }) => setActiveItem(name)}
/>
<Menu.Item
name={LETTER}
active={activeItem === LETTER}
onClick={(e, { name }) => setActiveItem(name)}
/>
</Menu>
<div>{renderData(data, activeItem)}</div>
</div>
);
};
export default BaseCase;
单击数字仅显示数字,其他一切都按预期工作。现在我的组件不起作用。我将数据保存在一个单独的文件中,如下所示:
import { BASH, DATA_SCIENCE, WEB_DEV, ALL } from '../constants';
const data = [
{
tags: [ALL],
title: 'Concussion App for Athletes',
.
.
.
},
{
tags: [DATA_SCIENCE, ALL],
title: 'Deep Learning: Exploring Car Value with an ANN',
...
},
.
.
.
];
export default data;
这是我的组件。我尝试了一些注释掉的代码,但也显示了不正确的组件。
import React, { useState } from 'react';
import ProjectCardContainer from '../../containers/ProjectCardContainer';
import { Menu } from 'semantic-ui-react';
import { ALL, BASH, DATA_SCIENCE, WEB_DEV } from './constants';
import data from './project_data';
import './Projects.scss';
const styles = {
container: {
display: 'flex',
justifyContent: 'space-around'
},
columns: {
display: 'flex',
flexDirection: 'column',
marginTop: '11px'
}
};
const renderColumn = (projectList, filterTag) => {
let projects = projectList.filter(proj => {
return proj['tags'].includes(filterTag);
});
return (
<div style={styles.columns}>
{projects.map(project => {
return <ProjectCardContainer project={project} />;
})}
</div>
);
};
const Projects = () => {
const [activeItem, setActiveItem] = useState(ALL);
// const [, updateState] = React.useState();
// const forceUpdate = useCallback(() => updateState({}), []);
// useEffect(() => {
// setTimeout(forceUpdate, 100);
// }, [activeItem]);
return (
<div>
<div className='second-nav-container'>
<Menu inverted stackable fluid widths={4}>
<Menu.Item
name={ALL}
active={activeItem === ALL}
onClick={(e, { name }) => setActiveItem(name)}
/>
<Menu.Item
name={WEB_DEV}
active={activeItem === WEB_DEV}
onClick={(e, { name }) => setActiveItem(name)}
/>
<Menu.Item
name={DATA_SCIENCE}
active={activeItem === DATA_SCIENCE}
onClick={(e, { name }) => setActiveItem(name)}
/>
<Menu.Item
name={BASH}
active={activeItem === BASH}
onClick={(e, { name }) => setActiveItem(name)}
/>
</Menu>
</div>
<div style={styles.container}>{renderColumn(data, activeItem)}</div>
</div>
);
};
export default Projects;
基本上,渲染的组件列表通常是不正确的,除非刷新页面并使用来自 useState() 的默认值。从菜单中选择不会显示正确类别的组件。
我认为问题在于在更新 activeItem 之前调用了渲染函数,但我不确定如何解决该问题。我对使用钩子有点陌生,但这似乎是一个必须经常出现的问题。
有人知道如何使用这样的菜单过滤数据,然后仅根据过滤后的数据显示特定组件吗?
【问题讨论】:
-
只是为了澄清 - 你有一个带有标签列表的下拉菜单,当你选择一个特定的标签时,你想渲染来自
data的所有具有该标签的对象?跨度> -
没关系,我看到了这个例子。 1 分钟
标签: javascript reactjs react-hooks