Next.js在状态改变时不重新渲染UI



在我的Next js项目中,我正在循环一系列显示div的便利设施,当单击切换活动道具时。addAmenity函数处理循环遍历便利设施数组的逻辑,并切换特定数组项的活动属性。如果div的活动属性为true,则. facilities -active类应该应用于它,并且div的背景应该变为绿色,但它没有。你知道我做错了什么吗?console.log(tempList)确认当点击一个false便利性时更改为true,但UI不会更改为具有绿色背景色。

//Next js
const amenitiesDefaultArr = [
{
data: "bathroom",
text: "Private Bathroom",
icon: <WcIcon fontSize="large" />,
active: false,
},
{
data: "dining",
text: "Dining Hall",
icon: <FastfoodIcon fontSize="large" />,
active: false,
},
{
data: "wifi",
text: "Wifi",
icon: <WifiIcon fontSize="large" />,
active: false,
}
]
const addAmenity = (e) => { 
let dataItem = e.currentTarget.dataset.amenity
let tempList = amenitiesList
tempList.map(el => {
if (el.data === dataItem) el.active = !el.active
return el
})
console.log(tempList)
setAmenitiesList(tempList)
}
const AddDorm = () => {
const [amenitiesList, setAmenitiesList] = useState(amenitiesDefaultArr)
return (
<>
{
amenitiesList.map(el => {
const {data, text, icon } = el
let { active } = el
return (
<div 
className={`amenity ${active && `amenity-active`}`} 
key={data} 
data-amenity={data}
onClick={(e) => addAmenity(e)}
>
<p>{text}</p>
{icon}
</div>
)
</>
})   
)
/* CSS */
.amenity {
padding: 0.5rem 1rem;
display: flex;
align-items: center;
border-radius: 50px;
box-shadow:  5px 5px 10px #919191,
-5px -5px 10px #ffffff;
z-index: 4;
cursor: pointer;
}
.amenity-active {
background-color: var(--green);
}

主要问题是您试图在JSX元素中传递数据,就像您在html中所做的那样。

data-amenity={data}

React就是这样工作的。因此,e.currentTarget.dataset.amenity总是undeined.相反,React使用refs来访问dom元素。你可以在官方的React文档中了解更多关于ref的信息。但在您的情况下,您甚至不需要任何ref,因为您可以直接向任何函数发送数据。检查:

<div 
className={`amenity ${active && `amenity-active`}`} 
key={data} 
// data-amenity={data}
onClick={() => addAmenity(data)}
>
<p>{text}</p>
</div>

addAmenity中只接收它

const addAmenity = (incoming) => {
let dataItem = incoming
...
}

下面我提供你的代码的版本,我为你修复这是完美的工作。如果这对我有帮助,请告诉我。

//Next js
import { useState } from 'react'
const amenitiesDefaultArr = [
{
data: "bathroom",
text: "Private Bathroom",
icon: <WcIcon fontSize="large" />,
active: false,
},
{
data: "dining",
text: "Dining Hall",
icon: <FastfoodIcon fontSize="large" />,
active: false,
},
{
data: "wifi",
text: "Wifi",
icon: <WifiIcon fontSize="large" />,
active: false,
}
]

const AddDorm = () => {
const [amenitiesList, setAmenitiesList] = useState(amenitiesDefaultArr)
const addAmenity = (incoming) => {
let dataItem = incoming
const tempList = amenitiesList.map(el => {
if (el.data === dataItem) el.active = !el.active
return el
})
console.log(tempList)
setAmenitiesList(tempList)
}
return (
<>
{
amenitiesList.map(el => {
const {data, text, icon} = el
let { active } = el
return (
<div 
className={`amenity ${active && `amenity-active`}`} 
key={data} 
// data-amenity={data}
onClick={() => addAmenity(data)}
>
<p>{text}</p>
{icon}
</div>
)})}
</> 
)
}
export default AddDorm

最新更新