首先单击不在反应中重新渲染组件

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 */);