React-Leaflet 多层中的相同标记
React-Leaflet same marker in multiple Layers
如何在 react-leaflet 的多个图层中添加相同的标记?
例如:
我有一个应用程序可以用 React 传单搜索餐厅,每个标记都是不同的餐厅。我想要一个 LayerControl
来按类型和评级(1..5 星)过滤它们。
我可以使用 LayerControl.Overlay
按类型(例如自助餐)进行过滤,但我还想按评级进行过滤。如果我有一家餐厅类型='buffet' 和评级=4,我该如何做才能仅在选中自助餐类型和 4 星评级时显示标记。
这是我的 current code,仅按类型过滤。
我正在使用 react-leaflet v3。
您使用的创建各种图层组来管理过滤器的方法并不是最好的方法。我采取了另一种方法。
使用所需过滤器创建状态对象
在您的应用中,创建一个包含潜在过滤器的状态变量。我们将其设置为最初包含所有选项:
const restaurantTypes = ["Family Style", "Buffet", "Fast Food", "Cafe"];
const ratings = [1, 2, 3, 4, 5];
function App() {
const [filters, setFilters] = useState({
restaurantTypes,
ratings
});
...
}
自定义过滤器组件
我选择创建一个自定义组件,它基本上与传单层控件完全相同 html 标记,但没有任何功能。您可以查看此答案末尾的沙箱,但它所做的只是管理我们刚刚定义的 filters
状态变量。这是一个简短的总结:
const FilterControl = ({ filters, setFilters }) => {
return (
<div>
<h3>Type</h3>
{restaurantTypes.map((type) => (
<label>
<input
type="checkbox"
checked={filters.restaurantTypes.includes(type)}
onClick={(e) => {
if (filters.restaurantTypes.includes(type)) {
setFilters((prevFilters) => ({
...prevFilters,
restaurantTypes: prevFilters.restaurantTypes.filter(
(f) => f !== type
)
}));
} else {
setFilters((prevFilters) => ({
...prevFilters,
restaurantTypes: [...prevFilters.restaurantTypes, type]
}));
}
}}
/>
<span>{type}/span>
</label>
))}
<h3>Rating</h3>
{ratings.map((rating) => (
// same as above but for ratings
))}
</div>
);
};
所以现在你的 FilterControl
可以巧妙地管理 filters
的状态。
根据过滤器过滤标记
现在您所要做的就是映射您的 restaurants
数据集,并且只渲染 type
和 rating
在当前 filters
中的标记:
function App() {
const [filters, setFilters] = useState({
restaurantTypes,
ratings
});
return (
<MapContainer ... >
<TileLayer ... />
<FilterControl filters={filters} setFilters={setFilters} />
{restaurants.map((restaurant) => {
if (
filters.restaurantTypes.includes(restaurant.type) &&
filters.ratings.includes(restaurant.rating)
) {
return <Marker position={restaurant.coordinates} />
}
return null;
})}
</MapContainer>
);
}
Working codesandbox
如何在 react-leaflet 的多个图层中添加相同的标记?
例如:
我有一个应用程序可以用 React 传单搜索餐厅,每个标记都是不同的餐厅。我想要一个 LayerControl
来按类型和评级(1..5 星)过滤它们。
我可以使用 LayerControl.Overlay
按类型(例如自助餐)进行过滤,但我还想按评级进行过滤。如果我有一家餐厅类型='buffet' 和评级=4,我该如何做才能仅在选中自助餐类型和 4 星评级时显示标记。
这是我的 current code,仅按类型过滤。
我正在使用 react-leaflet v3。
您使用的创建各种图层组来管理过滤器的方法并不是最好的方法。我采取了另一种方法。
使用所需过滤器创建状态对象
在您的应用中,创建一个包含潜在过滤器的状态变量。我们将其设置为最初包含所有选项:
const restaurantTypes = ["Family Style", "Buffet", "Fast Food", "Cafe"];
const ratings = [1, 2, 3, 4, 5];
function App() {
const [filters, setFilters] = useState({
restaurantTypes,
ratings
});
...
}
自定义过滤器组件
我选择创建一个自定义组件,它基本上与传单层控件完全相同 html 标记,但没有任何功能。您可以查看此答案末尾的沙箱,但它所做的只是管理我们刚刚定义的 filters
状态变量。这是一个简短的总结:
const FilterControl = ({ filters, setFilters }) => {
return (
<div>
<h3>Type</h3>
{restaurantTypes.map((type) => (
<label>
<input
type="checkbox"
checked={filters.restaurantTypes.includes(type)}
onClick={(e) => {
if (filters.restaurantTypes.includes(type)) {
setFilters((prevFilters) => ({
...prevFilters,
restaurantTypes: prevFilters.restaurantTypes.filter(
(f) => f !== type
)
}));
} else {
setFilters((prevFilters) => ({
...prevFilters,
restaurantTypes: [...prevFilters.restaurantTypes, type]
}));
}
}}
/>
<span>{type}/span>
</label>
))}
<h3>Rating</h3>
{ratings.map((rating) => (
// same as above but for ratings
))}
</div>
);
};
所以现在你的 FilterControl
可以巧妙地管理 filters
的状态。
根据过滤器过滤标记
现在您所要做的就是映射您的 restaurants
数据集,并且只渲染 type
和 rating
在当前 filters
中的标记:
function App() {
const [filters, setFilters] = useState({
restaurantTypes,
ratings
});
return (
<MapContainer ... >
<TileLayer ... />
<FilterControl filters={filters} setFilters={setFilters} />
{restaurants.map((restaurant) => {
if (
filters.restaurantTypes.includes(restaurant.type) &&
filters.ratings.includes(restaurant.rating)
) {
return <Marker position={restaurant.coordinates} />
}
return null;
})}
</MapContainer>
);
}