Reactjs trigger onClick function without click in functional component

I’m using functional component in react js , my onClick function triggers with component rendering without click on my li element ; this is my parent component that passed the handleCallDetails function as props to child component:

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>     );  } 

and it is my child compnent that use onClick function that named callDetails:

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>     );  } 

please help me to solve this problem without convert my functional component to class component and binding my function

Add Comment
4 Answer(s)

The correct way is this. You need to use arrow function or else react will understand that you want to execute the function at load

wrong

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

correct

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

Change from

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

to

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

Also

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

But where did you define the const [mode, setMode] state

Add Comment

It seems you exec your callback function immediately as it renders based on your code:

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

It’s supposed to be:

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

Is that the issue?

Add Comment

It’s mainly because of piece of code onClick={(props.callDetails)(item.id)} in your child component. This code is actually executing callDetails function and passing the item.id value immediately. One way to handle this is to wrap your function.

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

A simple reason as to why onClick is not called when it is wrapped is because it is not directly passing in any value when initialised.

Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.