繁体   English   中英

反应.js | 如果我将 setState 作为回调 function 传递,则无限渲染,即使在解构道具之后也是如此

[英]React.js | Infinite render if I pass setState as a callback function, even after destructuring props

问题

我有一个子组件,它获取一些按钮 id-name 配置作为道具,根据这些配置呈现可选的 HTML 按钮,并将所选按钮的值(id)返回给 useEffect 挂钩下的回调 function。 但是它会导致无限渲染循环,因为我需要将道具作为依赖数组传递。 请注意,React.js 希望我解构 props,但即使我这样做,它仍然会导致无限渲染循环。

子组件

import React, {createRef, useState, useEffect} from "react";

const OptionButton = ({ buttons, buttonClass, callback }) => {

    const [value, setValue] = useState()
    const refArray = []
    const buttonWidth = ((100 - (Object.keys(buttons).length - 1)) - ((100 - (Object.keys(buttons).length - 1)) % Object.keys(buttons).length)) / Object.keys(buttons).length

    useEffect(() => {
        if (callback) {
            callback(value);
        }
    }, [value, callback])

    const select = (event) => {
        event.target.style.backgroundColor = "#10CB81"
        refArray.forEach((currentRef) => {
            if (currentRef.current.id !== event.target.id) {
                currentRef.current.style.backgroundColor = "#F5475D"
            }
        })
        setValue(event.target.id)
    }

    return(
        <span style={{display: "flex", justifyContent: "space-between"}}>
            {Object.entries(buttons).map((keyvalue) => {
                const newRef = createRef()
                refArray.push(newRef)
                return <button ref={newRef} id={keyvalue[0]} key={keyvalue[0]} className={buttonClass} onClick={select} style={{width: `${buttonWidth}%`}}>{keyvalue[1]}</button>
            })}
        </span>
    )
}

export default OptionButton

因此,正如您在此处看到的,我的子组件将按钮配置作为键值(按钮值-按钮名称)对,呈现这些按钮,当用户单击其中一个按钮时,它会获取该按钮的 id,将其设置为“值”常量使用 useState 钩子,然后将该值传递给父组件回调。

父组件

return(
    <OptionButton buttons={{"ButtonValue": "ButtonName", "Button2Value": "Button2Name"}} callback={(value) => this.setState({buttonState: value})} buttonClass="buttonclass"/>
)

如果我不在回调 function 中使用 this.setState 就好了。 例如,如果我只是这样做

(值)=> 控制台日志(值)

没有无限循环。 据我所知,只有当我尝试使用 setState 时才会发生这种情况。

我究竟做错了什么? 我怎样才能解决这个问题? 提前致谢。

存在无限循环的原因是因为您在useEffect中有callback作为依赖项。 你传递给组件的是你在每个新的渲染上传递一个新的callback function ,因此它总是因此进入useEffect 由于您使用的是类,请考虑将实例方法作为回调而不是箭头 function 作为此处传递。


另外,我认为您过度使用了 refs。 您还可以通过存储说单击按钮的 id 来实现您正在做的事情,然后动态设置所有按钮的样式,例如在map内部,如果当前按钮的 id 与存储的相同,则使用style object 中的#10CB81 bg 颜色,否则不同的。

还有更好的方法来检查单击了哪个 btn,请参见此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM