Chakra React Range Slider:onChange与JSON映射报错及Tooltip需求
Chakra UI RangeSlider 错误修复 + 数据映射 + Tooltip 实现
一、修复「Cannot read properties of undefined (reading 'value')」错误
Chakra UI 的 RangeSlider 组件的 onChange 回调不接收 DOM 事件对象,而是直接返回当前滑块的数值数组(格式为 [最小值, 最大值])。你之前写的 e.target.value 不符合组件 API 规范,这就是报错的核心原因。
修正后的 onChange 逻辑:
onChange={(values) => { setFilter({ ...filter, // 把滑块的最小/最大值存入filter,可根据需求命名字段 minPrice: values[0], maxPrice: values[1], }); }}
二、正确映射 JSON 数据(info 数组)
你现在把 info.map 生成的 <option> 直接 spread 到 RangeSlider 上是完全错误的——RangeSlider 不是 <select> 组件,不需要 option 标签。
如果你的需求是让滑块范围/刻度对应 info 里的 price 字段,正确做法是:
- 先从
info中提取所有价格,处理出最小、最大值 - 可设置
RangeSlider的min/max,或添加marks属性标记价格点
示例处理逻辑:
// 从info中提取价格并排序 const prices = info.map(item => item.price).sort((a, b) => a - b); const minPrice = prices.length ? prices[0] : 0; const maxPrice = prices.length ? prices[prices.length - 1] : 100000000000;
将处理后的数据应用到 RangeSlider:
<RangeSlider // ... 其他属性 defaultValue={[minPrice, maxPrice]} min={minPrice} max={maxPrice} // 可选:添加价格标记点 marks={prices.map(price => ({ value: price, label: `${price}` }))} > {/* ... 子组件 ... */} </RangeSlider>
三、实现滑块上方的 Tooltip 功能
用 Chakra UI 的 Tooltip 组件包裹 RangeSliderThumb,即可实现拖动时显示当前数值的效果:
<RangeSlider // ... 其他属性 > <RangeSliderTrack> <RangeSliderFilledTrack /> </RangeSliderTrack> {/* 第一个滑块的Tooltip */} <Tooltip label={filter.minPrice} placement="top" hasArrow > <RangeSliderThumb index={0} /> </Tooltip> {/* 第二个滑块的Tooltip */} <Tooltip label={filter.maxPrice} placement="top" hasArrow > <RangeSliderThumb index={1} /> </Tooltip> </RangeSlider>
完整修正后的代码
import { useState } from "react"; import { RangeSlider, RangeSliderTrack, RangeSliderFilledTrack, RangeSliderThumb, Tooltip, } from "@chakra-ui/react"; export default function InfoCard({ info }) { const [filter, setFilter] = useState({ minPrice: 50, maxPrice: 100, }); // 处理info数据,提取价格范围 const prices = info.map(item => item.price).sort((a, b) => a - b); const minPrice = prices.length ? prices[0] : 0; const maxPrice = prices.length ? prices[prices.length - 1] : 100000000000; return ( <RangeSlider colorScheme="red" onChange={(values) => { setFilter({ ...filter, minPrice: values[0], maxPrice: values[1], }); }} aria-label={["min", "max"]} onChangeEnd={(val) => console.log(val)} defaultValue={[minPrice, maxPrice]} min={minPrice} max={maxPrice} step={10} marks={prices.map(price => ({ value: price, label: `${price}` }))} > <RangeSliderTrack> <RangeSliderFilledTrack /> </RangeSliderTrack> <Tooltip label={filter.minPrice} placement="top" hasArrow > <RangeSliderThumb index={0} /> </Tooltip> <Tooltip label={filter.maxPrice} placement="top" hasArrow > <RangeSliderThumb index={1} /> </Tooltip> </RangeSlider> ); }
内容的提问来源于stack exchange,提问作者Spatial_TX
相关产品推荐
相关产品推荐

