im really new to react so i wanted to know what this cool text effect would look like if it was in react, could someone please help me with it?

https://codepen.io/Hyperplexed/pen/rNrJgrd

const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

let interval = null;

document.querySelector("h1").onmouseover = event => {  
  let iteration = 0;
  
  clearInterval(interval);
  
  interval = setInterval(() => {
    event.target.innerText = event.target.innerText
      .split("")
      .map((letter, index) => {
        if(index < iteration) {
          return event.target.dataset.value[index];
        }
      
        return letters[Math.floor(Math.random() * 26)]
      })
      .join("");
    
    if(iteration >= event.target.dataset.value.length){ 
      clearInterval(interval);
    }
    
    iteration += 1 / 3;
  }, 20);
}
body {
  display: grid;
  place-items: center;
  height: 100vh;
/*   background-color: black; */
  margin: 0rem;
  overflow: hidden;
}

h1 {
  font-family: 'Space Mono', monospace;
  font-size: clamp(3rem, 10vw, 10rem);
/*   color: white; */
  padding: 0rem clamp(1rem, 2vw, 3rem);
  border-radius: clamp(0.4rem, 0.75vw, 1rem);
}

h1:hover {
  background-color: white;
  color: black;
}

/* -- YouTube Link Styles -- */

body.menu-toggled > .meta-link > span {
  color: rgb(30, 30, 30);
}

#source-link {
  bottom: 60px;
}

#source-link > i {
  color: rgb(94, 106, 210);
}

#yt-link > i {
  color: rgb(239, 83, 80);
}

.meta-link {
  align-items: center;
  backdrop-filter: blur(3px);
  background-color: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  bottom: 10px;
  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.1);
  cursor: pointer;  
  display: inline-flex;
  gap: 5px;
  left: 10px;
  padding: 10px 20px;
  position: fixed;
  text-decoration: none;
  transition: background-color 400ms, border-color 400ms;
  z-index: 10000;
}

.meta-link:hover {
  background-color: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.meta-link > i, .meta-link > span {
  height: 20px;
  line-height: 20px;
}

.meta-link > span {
  color: white;
  font-family: "Rubik", sans-serif;
  font-weight: 500;
}
<h1 data-value="GOOGLE DEVELOPER STUDENT CLUB">GOOGLE DEVELOPER STUDENT CLUB</h1>

<a id="source-link" class="meta-link" href="https://kprverse.com" target="_blank">
  <i class="fa-solid fa-link"></i>
  <span>Source</span>
</a>

<a id="yt-link" class="meta-link" href="https://youtu.be/W5oawMJaXbU" target="_blank">
  <i class="fa-brands fa-youtube"></i>
  <span>2 min tutorial</span>
</a>

the code in the above codepen link is written in plain html css js, i wanted to learn how to do it in react using hooks. if someone could let me know how to do it or do it and show it to me, it’d be of great help.

as i dont know react properly, im having a hard time implenting the effect in react.

>Solution :

Use a ref to store the interval ID and the rest of the code is roughly the same.

const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

function App() {
  const intvl = React.useRef();
  function animateText(event) {
    let iteration = 0;
    clearInterval(intvl.current);
    intvl.current = setInterval(() => {
      event.target.innerText = event.target.innerText
        .split("")
        .map((letter, index) => {
          if (index < iteration) {
            return event.target.dataset.value[index];
          }
          return letters[Math.floor(Math.random() * 26)]
        })
        .join("");
      if (iteration >= event.target.dataset.value.length) {
        clearInterval(intvl.current);
      }
      iteration += 1 / 3;
    }, 30);
  }
  return <h1 data-value="HYPERPLEXED" onMouseOver={animateText}>HYPERPLEXED</h1>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
body{display:grid;place-items:center;height:100vh;background-color:#000;margin:0;overflow:hidden}h1{font-family:'Space Mono',monospace;font-size:clamp(3rem, 10vw, 10rem);color:#fff;padding:0 clamp(1rem,2vw,3rem);border-radius:clamp(.4rem,.75vw,1rem)}h1:hover{background-color:#fff;color:#000}body.menu-toggled>.meta-link>span{color:#1e1e1e}#source-link{bottom:60px}#source-link>i{color:#5e6ad2}#yt-link>i{color:#ef5350}.meta-link{align-items:center;backdrop-filter:blur(3px);background-color:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);border-radius:6px;bottom:10px;box-shadow:2px 2px 2px rgba(0,0,0,.1);cursor:pointer;display:inline-flex;gap:5px;left:10px;padding:10px 20px;position:fixed;text-decoration:none;transition:background-color .4s,border-color .4s;z-index:10000}.meta-link:hover{background-color:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2)}.meta-link>i,.meta-link>span{height:20px;line-height:20px}.meta-link>span{color:#fff;font-family:Rubik,sans-serif;font-weight:500}
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

Leave a Reply