我的应用程序使用React typescript。我使用redux和saga进行状态管理。我获取了数据,并成功地显示在浏览器与谷歌地图。如果任何人悬停的属性,它将显示在地图上。现在我决定使用搜索选项来搜索属性。我过滤了属性的名称,然后包括我当地的州。 我的搜索输入在控制台中工作正常。我在地图上显示该州并尝试显示属性,它多次显示相同的属性名称。下面是图片. 我不知道怎么解决。我编辑了问题并删除了三元操作符。
import React, { useEffect, lazy, useState } from "react";
import styled from "styled-components";
import ErrorBoundary from "components/errorBoundary";
import { useDispatch, useSelector } from "react-redux";
import { IDashboardProperties } from "../../state/properties/reducer";
import { fetchProperties } from "../../state/properties/actions";
import { IIssueListItem } from "../../state/issues/types";
import { fetchIssuesList } from "../../state/issues/actions";
import { ICombinedReducers } from "../../state";
import TestMaps from "./TestMaps";
import LogoSpinner from "components/loaders/logoSpinner";
const SectionTemplate = lazy(() =>
import(`../../templates/primary/sectionTemplate`)
);
export interface ITestNewListProps {
className?: string;
}
const Test = ({ className }: ITestNewListProps) => {
const dispatch = useDispatch();
const properties: IDashboardProperties["data"] | undefined = useSelector(
(state: ICombinedReducers["properties"]) => state.properties.list.data
);
const issues: IIssueListItem | undefined = useSelector(
(state: ICombinedReducers) => state.issues.list.data
);
useEffect(() => {
// fetch the properties data from the api if we don't already have it
!properties && dispatch(fetchProperties({}));
}, [dispatch, properties]);
useEffect(() => {
!issues && dispatch(fetchIssuesList());
}, [dispatch, issues]);
const [hoveredProperty, setHoveredProperty] = useState<string | undefined>(
undefined
);
const [searchItem, setsearchItem] = useState(``); //THIS IS THE SEARCH STATE
console.log(`properties`, properties);
console.log(`issues`, issues);
const propertiesSorted: any[] = [];
const markersSorted: any[] = [];
let propertyInfo: any = {};
properties?.forEach((currProperty) => {
propertiesSorted.push({
name: currProperty.name,
uuid: currProperty.uuid,
address: "",
aliases: "",
city: "",
isHovered: hoveredProperty === currProperty.uuid,
});
if (hoveredProperty === currProperty.uuid) {
propertyInfo = {
name: currProperty.name,
total: currProperty.serviceRequests.uncompleted.length,
old: currProperty.serviceRequests.uncompletedAfterFiveDays.length,
reportedToday: currProperty.serviceRequests.createdToday.length,
task: currProperty.tasks.overdue.length,
};
}
currProperty.addresses.forEach((i: any, index) => {
markersSorted.push({
key: index,
lat: i.coordinates.latitude,
lng: i.coordinates.longitude,
name: i.property.name,
isHovered: hoveredProperty === currProperty.uuid,
});
});
});
const Search = (e: any) => { //THIS IS THE INPUT FUNCTION
setsearchItem(e.target.value);
};
const nameFilter: any | [] = properties?.filter((list) => {
return list.name.toLowerCase().includes(searchItem.toLowerCase());
}); //IN HERE I FILTERED THE PROPERTIES AND ADD IT TO THE `searchItem` STATE.
console.log(`Name filter`, nameFilter); // search result works
console.log("propertyInfoCopy", propertyInfo);
return (
<ErrorBoundary id="TestNewListErrorBoundary">
<SectionTemplate>
<div className={className}>
<div className="properties-list-sidebar">
<input placeholder="search property" onChange={Search} />
<br /> <br />
<div>
//THIS IS WHERE I AM DOING MAPPING
{nameFilter?.map((i: any) => (
<div>
{propertiesSorted?.map((i) => (
<div
className={
i.isHovered
? "property-item property-item-hovered"
: "property-item"
}
key={i.uuid}
onMouseEnter={() => setHoveredProperty(i.uuid)}
>
Name: {i.name}
</div>
))}
</div>
))}
</div>{" "}
</div>
<div className="properties-list-map">
{hoveredProperty && (
<div
style={{
position: "absolute",
top: 100,
right: 30,
zIndex: 2,
background: "pink",
padding: 20,
}}
>
Name: {propertyInfo.name} <br />
<h2>Service requests</h2>
<p>Unassigned: {propertyInfo.old}</p>
<p>Uncompleted: {propertyInfo.total}</p>
</div>
)}
{properties ? (
<TestMaps markers={markersSorted} />
) : (
<LogoSpinner />
)}
</div>
</div>
</SectionTemplate>
</ErrorBoundary>
);
};
Test.displayName = `Test`;
export default styled(Test)`
display: flex;
align-items: flex-start;
align-content: flex-start;
.properties-list-sidebar {
flex: 0;
width: 300px;
flex-basis: 300px;
height: 100%;
background: white;
}
.properties-list-map {
flex: 1;
height: 100%;
}
.property-item {
margin-bottom: 20px;
&:hover {
background-color: yellow;
}
}
.Notfound {
position: absolute;
top: 50%;
left: 50%;
color: red;
}
.property-item-hovered {
background-color: yellow;
}
`;
似乎你在属性数组上进行过滤,但你渲染的是第108行的propertiesSorted数组,你只推送到该数组,而从未从该数组中删除任何内容。而且你对nameFilter包含的每个项目都渲染一次整个propertiesSorted数组。
这个未经测试的代码段不包含你的propertiesSorted数组,所以它不能解决你的代码,但也许它可以让你开始。
{nameFilter.length ? nameFilter?.map((i: any, name, uuid, isHovered ) =>
<div
className={
isHovered
? "property-item property-item-hovered"
: "property-item"
}
key={uuid}
onMouseEnter={() => setHoveredProperty(uuid)}
>
Name: {name}
</div>
) : (
<h1>Sorry property not found</h1>
)
)}
问题是 nameFilter
变量没有得到更新。
const Test = ({ className }: ITestNewListProps) => {
const [filterNames, setFilteredNames] = useState([]);
const dispatch = useDispatch();
/*
. REST OF THE CODE
.
*/
const nameFilter: any | [] = properties?.filter((list) => { //In
return list.name.toLowerCase().includes(searchItem.toLowerCase());
});
setFilteredNames(nameFilter);// Set state variable here
使用 filteredNames
在回车语句中,而不是 nameFilter