首先单击不在反应中重新渲染组件
First click not re-rendering component in react
我正在尝试创建一个简单的应用程序组件,该组件将被多次使用,并且可能会以某种类型的网格格式呈现 30 次。这个组件只是一个真正具有某些功能的图标。我希望能够更改我单击的图标的颜色。假设我要渲染此组件 50 次,然后单击图标 34,然后我只想让图标 34 更改颜色。
这些组件都将使用默认值 'green' 或 false...
进行渲染
问题:
这个问题似乎是我对 React 不了解的一些基本问题。对反应有更多了解的人也许可以解释发生了什么。
这里是问题的详细描述。
所以我能够像我之前所说的那样渲染组件 50 次。看起来有点像这样
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
它们一开始都是绿色的,但当我第一次点击一个时没有任何反应,但第二次后图标按预期从绿色变为红色。我理解的逻辑是合理的。
我采用原始状态 'false',因此每本书的 selected 值都会变为 false。
如果值为 false,则颜色变量上的 useState 的初始值为 'green'
所以:
已选择=假;
颜色=绿色;
单击图标时,它会运行下面的句柄函数。
该函数会将 selected 设置为与当前相反的值,因此它会从 false 变为 true
所以:
选择=真;
颜色=绿色;
接下来该函数将检查所选内容是真还是假。如果它是真的,它会将颜色更改为红色。但这不是第一次发生的情况。第一次点击什么都不做。我假设它正在将其更改为绿色,但我无法分辨,因为它已经是绿色的,除非这是一个错误的假设。
这是更好地重现我的问题的代码
import react, {useState} from 'react'
import { FaBook } from 'react-icons/fa'
export default function BookIconFunc(props) {
const [selected, setSelected] = useState(props.checkedOut)
const [color, setColor] = useState(selected ? 'red' : 'green')
/*
if selected = false that means it is available
when clicked it should turn red
*/
const handleColorChange = () => {
console.log("HELLO")
setSelected(!selected)
if(selected){
setColor('red')
} else {
setColor('green')
}
}
const indBook = {
margin: "0.5rem",
color: color
}
return <FaBook style={indBook} size={32} onClick={handleColorChange}>
</FaBook>
我在一个单独的组件中这样做
array = [1,2,3,4,5,6,7,8]
array.map((arr, index) => {
<BookIconFunc checkedOut={false}/>
}
我可以说我对 React 有一些不完全理解的地方。我只是不确定那是什么。我对这门语言很陌生。感谢您的帮助。
您遇到的问题是 setSelected
异步的结果。
在handleColorChange
中检查if(selected)
时选择的仍然是之前的值。
解决此问题的方法是临时存储新计算的值以供进一步计算使用,例如:
const handleColorChange = () => {
const newValue = !selected;
setSelected(!newValue);
if(newValue){
setColor('red')
} else {
setColor('green')
}
}
如果我可以提出一个建议,如果颜色直接依赖于 selected 的值,那么你最好不要存储该值,而只是在每次渲染时计算它。例如:
const color = selected ? 'red' : 'green';
将来如果你有一个更复杂的计算,只依赖于其他变量的值,那么你可以使用 useMemo
。例如:
const color = useMemo(() => {
// usually a more complex / costly calculation.
return selected ? 'red' : 'green';
}, [selected] /* Only update on change of selected */);
我正在尝试创建一个简单的应用程序组件,该组件将被多次使用,并且可能会以某种类型的网格格式呈现 30 次。这个组件只是一个真正具有某些功能的图标。我希望能够更改我单击的图标的颜色。假设我要渲染此组件 50 次,然后单击图标 34,然后我只想让图标 34 更改颜色。
这些组件都将使用默认值 'green' 或 false...
进行渲染问题:
这个问题似乎是我对 React 不了解的一些基本问题。对反应有更多了解的人也许可以解释发生了什么。
这里是问题的详细描述。
所以我能够像我之前所说的那样渲染组件 50 次。看起来有点像这样
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
[ * * * * * * * * * * ]
它们一开始都是绿色的,但当我第一次点击一个时没有任何反应,但第二次后图标按预期从绿色变为红色。我理解的逻辑是合理的。
我采用原始状态 'false',因此每本书的 selected 值都会变为 false。
如果值为 false,则颜色变量上的 useState 的初始值为 'green'
所以:
已选择=假; 颜色=绿色;
单击图标时,它会运行下面的句柄函数。
该函数会将 selected 设置为与当前相反的值,因此它会从 false 变为 true
所以: 选择=真; 颜色=绿色;
接下来该函数将检查所选内容是真还是假。如果它是真的,它会将颜色更改为红色。但这不是第一次发生的情况。第一次点击什么都不做。我假设它正在将其更改为绿色,但我无法分辨,因为它已经是绿色的,除非这是一个错误的假设。
这是更好地重现我的问题的代码
import react, {useState} from 'react'
import { FaBook } from 'react-icons/fa'
export default function BookIconFunc(props) {
const [selected, setSelected] = useState(props.checkedOut)
const [color, setColor] = useState(selected ? 'red' : 'green')
/*
if selected = false that means it is available
when clicked it should turn red
*/
const handleColorChange = () => {
console.log("HELLO")
setSelected(!selected)
if(selected){
setColor('red')
} else {
setColor('green')
}
}
const indBook = {
margin: "0.5rem",
color: color
}
return <FaBook style={indBook} size={32} onClick={handleColorChange}>
</FaBook>
我在一个单独的组件中这样做
array = [1,2,3,4,5,6,7,8]
array.map((arr, index) => {
<BookIconFunc checkedOut={false}/>
}
我可以说我对 React 有一些不完全理解的地方。我只是不确定那是什么。我对这门语言很陌生。感谢您的帮助。
您遇到的问题是 setSelected
异步的结果。
在handleColorChange
中检查if(selected)
时选择的仍然是之前的值。
解决此问题的方法是临时存储新计算的值以供进一步计算使用,例如:
const handleColorChange = () => {
const newValue = !selected;
setSelected(!newValue);
if(newValue){
setColor('red')
} else {
setColor('green')
}
}
如果我可以提出一个建议,如果颜色直接依赖于 selected 的值,那么你最好不要存储该值,而只是在每次渲染时计算它。例如:
const color = selected ? 'red' : 'green';
将来如果你有一个更复杂的计算,只依赖于其他变量的值,那么你可以使用 useMemo
。例如:
const color = useMemo(() => {
// usually a more complex / costly calculation.
return selected ? 'red' : 'green';
}, [selected] /* Only update on change of selected */);