React

Demo of useEffect behaving differently when inside a custom hook - passing ref.current.

by GreenAsJade

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.clickme {
  color: red;
}

input {
  margin-right: 5px;
}

React

const useCustomHookWithUseEffect = (el1, el2) => {
	  React.useEffect(() => {
  	console.log("CUSTOM Use effect...");
    console.log("firstRef element defined", !!el1);
    console.log("secondRef element", !!el2);
  }, [el1, el2]);
}

const RefDemo = () => {
	const [vis, setVis] = React.useState(false);
  
  const firstRef = React.useRef(null);
  const secondRef = React.useRef(null);
  
  useCustomHookWithUseEffect(firstRef.current, secondRef.current);
  
  React.useEffect(() => {
  	console.log("Standard Use effect...");
    console.log("firstRef element defined", !!firstRef.current);
    console.log("secondRef element ", !!secondRef.current);
    }, [firstRef.current, secondRef.current]);
    
  console.log("At RefDemo render", !!firstRef.current , !!secondRef.current);
    
 	return (
  	<div>
      <div ref={firstRef}>
        My ref is created in the initial render
      </div>
      <div className="clickme" onClick={() => setVis(true)}>
        click me
      </div>
      {vis && 
      	<div ref={secondRef}>boo (second ref must surely be valid now?)</div>
      }
    </div>
    )
}

const container = document.getElementById('app');
const root = ReactDOM.createRoot(container);
root.render(<RefDemo />);