REACT:使用 setState 钩子重新渲染组件时出错
REACT : getting error while re-rendering components using setState hook
我正在尝试更改几个项目的内联样式 属性,这些项目的位置信息存储在 useState 挂钩中,以及每个呈现的项目的样式 属性。我想更改所有项目的 CSS 值,但我单击的项目除外。我设计了一个函数来执行此操作,但是当我尝试使用 setState 更新 CSS 值时,项目不会重新呈现并且我收到一条错误消息“discs.map 不是函数”。我是否正确使用了设置状态挂钩?我应该使用 setState 挂钩来完成这样的任务,即设置项目的动画位置吗?
// 主要成分
function App() {
const [discs, setDiscs] = useState([
{ id: 1, top: 100 },
{ id: 2, top: 200 },
{ id: 3, top: 300 },
{ id: 4, top: 400 },
{ id: 5, top: 500 },
{ id: 6, top: 600 },
{ id: 7, top: 700 },
{ id: 8, top: 800 },
{ id: 9, top: 900 },
{ id: 10, top: 1000 },
{ id: 11, top: 1100 },
{ id: 12, top: 1300 }
])
function enlargeDisc(e, num) {
let t = e.target
if (t.classList.contains('active')) {
t.classList.remove('active')
adjustDiscPos(num, true)
} else {
t.classList.add('active')
adjustDiscPos(num, false)
}
}
function adjustDiscPos(n, backToOriginal) {
console.log(discs)
discs.forEach((disc) => {
if (disc.id < n) {
setDiscs(prevState => backToOriginal ? prevState + 300 : prevState - 300)
}
if (disc.id > n) {
setDiscs(prevState => backToOriginal ? prevState - 300 : prevState + 300)
}
})
}
return (
<div className="App">
<div className="container">
<div className="wrapper" style={{bottom: scroll}}>
{discs.map((item) => (
<div className ='disc' key={item.id} data-index={item.id} style={{top: item.top + 'px'}} onClick={(e)=> enlargeDisc(e, item.id)} ></div>
))}
</div>
</div>
</div>
);
}
export default App;
CSS
.disc {
position: absolute;
transform:
translate(-50%, -50%) rotateX(90deg) scale(1);
width: 10em;
height: 10em;
transform-style: preserve-3d;
cursor: pointer;
background-image:
radial-gradient(rgba(0, 0, 0, 0), rgb(22, 22, 22) 95%),
url('./img/cd3.png');
background-size: 100% 100%;
transition: all 0.5s ease-in-out;
}
.disc.active {
transform:
translate(-50%, -50%) rotateX(0deg) scale(1.5);
}
在 adjustDiscPos
中,您正在调用 setDiscs
和 300
prevState - 300
.
的减法值
这会将 NaN
推送到 discs
,从而导致您的错误。
您应该在 forEach
中计算一个新数组,然后只调用 setDiscs
一次。
以 Radu Dita 所说的为基础
In adjustDiscPos you are calling setDiscs with the value of a subtraction of an array and 300 prevState - 300.
This will push NaN to discs and hence your error.
You should compute a new array in your forEach and then call setDiscs only once.
这意味着您应该使用 setDiscs
一次(prevState
是对当前 discs
值的引用),并通过 map
或其他方式对其进行 arrayu 操作。
function adjustDiscPos(n, backToOriginal) {
console.log(discs)
setDiscs(prevState => prevState.map(disc => {
const offset = backToOriginal ? 300 : -300;
return { id: disc.id, top: disc.id < n ? disc.top + offset : disc.top - offset };
})
请务必记住不要直接改变 prevState
,因为它是对当前状态变量的引用,而是使用一些数组函数 returns 一个新值。
我在这里假设它是您想要操纵的 top
的值。我还假设您希望 id 等于 n
的光盘保持原样。如果我错了,请纠正我。
您需要做的是创建一个临时数组并将新值添加到该数组。然后,完成后,您可以使用临时数组作为参数调用 setDiscs
。
let tmp_discs = [];
discs.forEach((disc) => {
if (disc.id < n) {
tmp_discs[disc.id] = backToOriginal ? disc.top + 300 : disc.top - 300;
} else if (disc.id > n) {
tmp_discs[disc.id] = backToOriginal ? disc.top - 300 : disc.top + 300;
} else {
tmp_discs[disc.id] = disc.top;
}
})
setDiscs(tmp_discs);
我正在尝试更改几个项目的内联样式 属性,这些项目的位置信息存储在 useState 挂钩中,以及每个呈现的项目的样式 属性。我想更改所有项目的 CSS 值,但我单击的项目除外。我设计了一个函数来执行此操作,但是当我尝试使用 setState 更新 CSS 值时,项目不会重新呈现并且我收到一条错误消息“discs.map 不是函数”。我是否正确使用了设置状态挂钩?我应该使用 setState 挂钩来完成这样的任务,即设置项目的动画位置吗?
// 主要成分
function App() {
const [discs, setDiscs] = useState([
{ id: 1, top: 100 },
{ id: 2, top: 200 },
{ id: 3, top: 300 },
{ id: 4, top: 400 },
{ id: 5, top: 500 },
{ id: 6, top: 600 },
{ id: 7, top: 700 },
{ id: 8, top: 800 },
{ id: 9, top: 900 },
{ id: 10, top: 1000 },
{ id: 11, top: 1100 },
{ id: 12, top: 1300 }
])
function enlargeDisc(e, num) {
let t = e.target
if (t.classList.contains('active')) {
t.classList.remove('active')
adjustDiscPos(num, true)
} else {
t.classList.add('active')
adjustDiscPos(num, false)
}
}
function adjustDiscPos(n, backToOriginal) {
console.log(discs)
discs.forEach((disc) => {
if (disc.id < n) {
setDiscs(prevState => backToOriginal ? prevState + 300 : prevState - 300)
}
if (disc.id > n) {
setDiscs(prevState => backToOriginal ? prevState - 300 : prevState + 300)
}
})
}
return (
<div className="App">
<div className="container">
<div className="wrapper" style={{bottom: scroll}}>
{discs.map((item) => (
<div className ='disc' key={item.id} data-index={item.id} style={{top: item.top + 'px'}} onClick={(e)=> enlargeDisc(e, item.id)} ></div>
))}
</div>
</div>
</div>
);
}
export default App;
CSS
.disc {
position: absolute;
transform:
translate(-50%, -50%) rotateX(90deg) scale(1);
width: 10em;
height: 10em;
transform-style: preserve-3d;
cursor: pointer;
background-image:
radial-gradient(rgba(0, 0, 0, 0), rgb(22, 22, 22) 95%),
url('./img/cd3.png');
background-size: 100% 100%;
transition: all 0.5s ease-in-out;
}
.disc.active {
transform:
translate(-50%, -50%) rotateX(0deg) scale(1.5);
}
在 adjustDiscPos
中,您正在调用 setDiscs
和 300
prevState - 300
.
这会将 NaN
推送到 discs
,从而导致您的错误。
您应该在 forEach
中计算一个新数组,然后只调用 setDiscs
一次。
以 Radu Dita 所说的为基础
In adjustDiscPos you are calling setDiscs with the value of a subtraction of an array and 300 prevState - 300. This will push NaN to discs and hence your error. You should compute a new array in your forEach and then call setDiscs only once.
这意味着您应该使用 setDiscs
一次(prevState
是对当前 discs
值的引用),并通过 map
或其他方式对其进行 arrayu 操作。
function adjustDiscPos(n, backToOriginal) {
console.log(discs)
setDiscs(prevState => prevState.map(disc => {
const offset = backToOriginal ? 300 : -300;
return { id: disc.id, top: disc.id < n ? disc.top + offset : disc.top - offset };
})
请务必记住不要直接改变 prevState
,因为它是对当前状态变量的引用,而是使用一些数组函数 returns 一个新值。
我在这里假设它是您想要操纵的 top
的值。我还假设您希望 id 等于 n
的光盘保持原样。如果我错了,请纠正我。
您需要做的是创建一个临时数组并将新值添加到该数组。然后,完成后,您可以使用临时数组作为参数调用 setDiscs
。
let tmp_discs = [];
discs.forEach((disc) => {
if (disc.id < n) {
tmp_discs[disc.id] = backToOriginal ? disc.top + 300 : disc.top - 300;
} else if (disc.id > n) {
tmp_discs[disc.id] = backToOriginal ? disc.top - 300 : disc.top + 300;
} else {
tmp_discs[disc.id] = disc.top;
}
})
setDiscs(tmp_discs);