Reactjs 触发 onClick 函数而不点击功能组件

Posted

技术标签:

【中文标题】Reactjs 触发 onClick 函数而不点击功能组件【英文标题】:Reactjs trigger onClick function without click in functional component 【发布时间】:2020-11-03 13:16:35 【问题描述】:

我在 react js 中使用功能组件,我的 onClick 函数触发组件渲染而无需单击我的 li 元素; 这是我的父组件,将 handleCallDetails 函数作为道具传递给子组件:

export default function Cartable()

    const [items , setItems] = useState(null);
    const [details , setDetails] = useState(null);



    function handleCallDetails(id)
        if(items !== null && details === null)
            let d = items.find(x => 
                return x.id === id;
            );

        
    

    useEffect(() => 
        axios.get(`/workflows/$mode` ,
            params : 
                OrganizationId : "FE905B40-DA6E-4A81-8A4F-B447AA6B0EA3" , 
                Type : 2 ,
                sortorder : "desc" ,
                pageIndedx : 1 , 
                pageSize : 10
            
        ).then(response => 
            // console.log('response : ***************** ' , response);
            setItems(response.data.data);
        ).catch(error => 
            console.log('error : ****************** ' , error);
        );
     , [mode]);

     
   
    return (
        <Grid container spacing=2>
            <Grid item xs=12 sm=4 md=3>
                <div className="drt_RightSide drt_segment">
                    <h4 className="drt_RightSideTitle">
                        <i className="far fa-inbox"></i>
                        کارتابل
                    </h4>
                    <ul>
                        /* <li>
                            <i class="far fa-inbox"></i>
                            <span>درخواست ها</span>
                        </li> */
                        <li onClick=() => setMode('pending');>
                            <i className="fas fa-exclamation"></i>
                            <span><FormattedMessage id="CARTABLE_PENDING" /></span>
                            <span className="drt_badge_warning drt_NotifNum">5</span>
                        </li>
                        <li onClick=() => setMode('approved');>
                            <i className="far fa-check"></i>
                            <span>تایید شده</span>
                        </li>
                        <li onClick=() => setMode('rejected');>
                            <i className="far fa-times"></i>
                            <span>رد شده</span>
                            <span className="drt_badge_error drt_NotifNum">7</span>
                        </li>
                        <li>
                            <i className="far fa-bell"></i>
                            <span>خارج از فرآیند</span>
                        </li>
                    </ul>
                </div>
            </Grid>
            <Grid item xs=12 sm=8 md=9>
                <div className="drt_LeftSide drt_segment">                 */
                        
                    /* cartbale list */
                    <CartableList
                        items=items
                        callDetails=handleCallDetails/>

                </div>
            </Grid>
        </Grid>
    );


我的子组件使用了名为 callDetails 的 onClick 函数:

export default function CartableList(props)

    const [showbox , setShowbox] = useState(false);
    const [age, setAge] = useState('');

    const handleChange = (event) => 
        setAge(event.target.value);
    ;

    function handleFilterBox()
        setShowbox(!showbox);
    


    return (
        <Fragment>
            
            /* cartable list */
            <div style=direction : "ltr">
                <Scrollbars style= height: 400 >

                    
                        props.items && props.items !== undefined ?
                            props.items.map(function(item , index)
                                
                                return (
                                    <div className="drt_clearfix drt_CartableItem" key=index onClick=(props.callDetails)(item.id)>
                                        /* <div className=clsx(drt_ItemStar , item.star ? drt_IsStared : '')>
                                            <span><i className=clsx(item.star ? "fas fa-star" : "fal fa-star")></i></span>
                                        </div> */
                                        <div className="drt_ItemImg">
                                            <span>
                                                <img alt=userImg src=item.pictureUrl !== undefined && item.pictureUrl !== null ? item.image : userImg />
                                            </span>
                                        </div>
                                        <div className=clsx("drt_ItemName" , !item.isSeen ? "drt_IsNotSeen" : '')>
                                            item.issuerFirstName
                                            <br />
                                            item.issuerLastname
                                        </div>
                                        <div className="drt_ItemIcon">
                                            <Tooltip title=(props.moduleType)(item.type).name>
                                                <span className=item.isSeen ? "drt_badge_default" : "drt_badge_primary">
                                                    <i className=(props.moduleType)(item.type).icon />
                                                </span>
                                            </Tooltip>
                                        </div>
                                        <div className=clsx("drt_ItemDesc" , !item.isSeen ? "drt_IsNotSeen" : '')>
                                            item.objectTitle
                                        </div>
                                        <div className="drt_ItemStatus">
                                            <span className=(props.stateClass)(item.status)>
                                                (props.stateTitle)(item.status)
                                            </span>
                                        </div>
                                        <div className=clsx("drt_ItemDate" , !item.isSeen ? "drt_IsNotSeen" : '')>
                                            <p>
                                                <span>
                                                    item.issuerTime
                                                </span>
                                                <span>
                                                    item.issuerDate
                                                </span>
                                            </p>
                                            <i className="fal fa-clock" />
                                        </div>
                                    </div>
                                );
                            ) : ''
                    
                    
                </Scrollbars>
            </div>
        </Fragment>
    );


请帮我解决这个问题,不要将我的功能组件转换为类组件并绑定我的功能

【问题讨论】:

【参考方案1】:

正确的做法是这样。您需要使用箭头函数,否则 react 会明白您要在加载时执行该函数

错误

<div className="drt_clearfix drt_CartableItem" key=index onClick=(props.callDetails)(item.id)>

正确

<div className="drt_clearfix drt_CartableItem" key=index onClick=() => props.callDetails(item.id)>

【讨论】:

【参考方案2】:

改变

onClick=() => setMode('rejected');

onClick=() => setMode('rejected')

还有

<div className="drt_clearfix drt_CartableItem" key=index onClick=() => props.callDetails(item.id)>

但是你在哪里定义 const [mode, setMode] 状态

【讨论】:

仅供参考,虽然 onClick=() =&gt; setMode('rejected'); 可以改进(编码风格方面),但它在技术上没有错误,也没有引起问题。 是的,我想是的。遵守约定【参考方案3】:

您的回调函数似乎根据您的代码呈现时立即执行:

onClick=(props.callDetails)(item.id)

应该是这样的:

onClick=() => props.callDetails(item.id)

是这个问题吗?

【讨论】:

【参考方案4】:

这主要是因为您的子组件中有一段代码onClick=(props.callDetails)(item.id)。这段代码实际上是在执行 callDetails 函数并立即传递 item.id 值。处理这个问题的一种方法是包装你的函数。

onClick=() =&gt; props.callDetails(item.id)

onClick 在包装时不被调用的一个简单原因是因为它在初始化时没有直接传递任何值。

【讨论】:

以上是关于Reactjs 触发 onClick 函数而不点击功能组件的主要内容,如果未能解决你的问题,请参考以下文章

onClick和onChange不会在reactjs中的safari单选按钮上触发

无法使 onClick 在 ReactJS 中工作

如何在 ReactJS Typescript 中 2 分钟后自动发生 onclick

Reactjs-onClick 事件在我第一次单击按钮时未触发

一个onclick事件触发一个函数,如何将该元素的对象作为函数的参数传过去

Reactjs/Apollo/AppSync Mutation 触发了两次