'Calling a function that was declared inside useEffect

i am very new to react. I as trying to add a signature module to a React component and everything worked fine so far. The module also offers a couple of methods, like clearing the canvas. My issue is, i have no idea where to set of the function in order to call it later in the render part. I have tried all possibilities (including useState, useRef) but cannot find a way to setup the function in a way so it is later.

So what i would like to access the clear method from the 3rd party library later in the return statement. I am aware useEffect was apparently not the right place to set the function up (however creating new SignaturePad works fine), but where would that be?

import SignaturePad from "signature_pad";


    function OtherInfo(){

useEffect(()=> {
    const canvas = document.getElementById("canvo")
    const signaturePad = new SignaturePad(canvas)
    
    // cannot be called later  
    const clear = signaturePad.clear()
}) 


    return (

<div className="spefcontainer">
<input type="text" placeholder="More..." />
<input type="text" placeholder="Stuff..."/>
<canvas id="canvo"> </canvas>
<button onClick={clear}>Clear</button>
</div>
);}

export default OtherInfo;


Solution 1:[1]

useEffect() hook used for render after event occurring same ad componentDidMount() and componentDidMountUpdate().

put that code outside useEffect() and create function 'clear' to call at the time of button click.

import SignaturePad from "signature_pad";


    function OtherInfo(){

   const clear = ()=> {
    const canvas = document.getElementById("canvo");
    const signaturePad = new SignaturePad(canvas);
    
    signaturePad.clear();
}) 


    return (

<div className="spefcontainer">
<input type="text" placeholder="More..." />
<input type="text" placeholder="Stuff..."/>
<canvas id="canvo"> </canvas>
<button onClick={clear}>Clear</button>
</div>
);}

export default OtherInfo;

Solution 2:[2]

Can you just put the code which clears the pad in a regular function inside the component? see below. Does it have to be inside useEffect for a particular reason?

You can try to wrap the function in useMemo, so it does not run every time the component is rendered. Also, consider whether you have to create the canvas and signature pad every time, or only the first time the element is rendered (in which case you can initialize them in useEffect with an empty dependency array maybe)

import SignaturePad from "signature_pad";

function OtherInfo(){

   let signaturePad;

   useEffect(()=> {
    const canvas = document.getElementById("canvo");
    signaturePad = new SignaturePad(canvas)
}, []); 

   function clear() {
    signaturePad.clear();
   }

    return (

    <div className="spefcontainer">
    <input type="text" placeholder="More..." />
    <input type="text" placeholder="Stuff..."/>
    <canvas id="canvo"> </canvas>
    <button onClick={clear}>Clear</button>
    </div>
);}

export default OtherInfo;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dhruval Bhuva
Solution 2