Home > Enterprise >  The text in Html is not changing even so variable text1 is changing in console log ,why?
The text in Html is not changing even so variable text1 is changing in console log ,why?

Time:01-31

This is a component in react. I am trying to create function that changes text every second. Variable changes every second it works but when i pass it in Html nothing happens on Page itself.

export default function Statement(){

    var text = ["NFT", "CRYPTO", "METAVERSE", "WEB3"];
    var counter = 0;
    var text1 = "NFT";
    setInterval(change, 1000);
    
    function change() {
      text1 = text[counter];
      counter  ;
      console.log(text1,counter);
      if (counter >= text.length) {
        counter = 0;
      }
    }
    
    return(
          
        <div>
            <img className='star-fixed' src={SmallLogo}></img>
            <img className='starsky-fixed' src={StarskyText}></img>
            <div className='text-content'>
                <span className='statement-text'>WEB3 IS NOT ONLY THE FUTURE.
                            IT’S THE ONLY FUTURE!</span>
                <span className='starsk-link'>starsk.pro</span>
            </div>
            <div className='text-content-bottom'>
               <span className='statement-text-bottom'>CREATE YOUR NEXT  <span className='yellow changetext'> {text1} </span>
                     PROJECT WITH STRSK.PRO</span>
            </div>
        </div>

    )

}

CodePudding user response:

Because the component doesn't re-render when the value of the variable is updated.. states are used to handle that..

You have to create a state of your variable and when that state changes, the component responds by re-rendering automatically.

https://reactjs.org/docs/faq-state.html

CodePudding user response:

The text isn't changing because the component only renders once. To get the component to re-render, you need to use state. Specifically, you need to use a state external to the component, like Redux, so your counter/index variable isn't reset on each render.

Additionally, the setInterval call needs to be moved outside of the component and called from a useEffect hook so it doesn't get rescheduled on each render.

Lastly, using another custom component specifically for the updated text seems to result in more normal rendering behavior, because only the child component needs to be re-rendered.

Here is some example code:

Redux store and reducer

import { createStore } from "redux";

const initialState = {
  tempText: "NFT",
  index: 1
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "updatetext":
      return {
        ...state,
        tempText: action.payload
      };
    case "updateindex":
      return {
        ...state,
        index: action.payload
      };
    default:
      return state;
  }
};

export const store = createStore(reducer);

App

function TempText(props) {
  return <span className="yellow changetext"> {props.body} </span>;
}

function doUpdate(callback) {
  setInterval(callback, 3000);
}

export default function App() {
  const dispatch = useDispatch();
  const textOptions = ["NFT", "CRYPTO", "METAVERSE", "WEB3"];
  const tempText = useSelector((state) => state.tempText);

  function change() {
    let state = store.getState(); 
    const index = state.index;
    console.log(index);
    console.log(textOptions[index]);
    dispatch({
      type: "updatetext",
      payload: textOptions[index]
    });
    let newIndex = index   1 >= textOptions.length ? 0 : index   1;
    dispatch({
      type: "updateindex",
      payload: newIndex
    });
  }

  useEffect(() => {
    doUpdate(change);
  }, []);

  return (
    <div>
      <div className="text-content">
        <span className="statement-text">
          WEB3 IS NOT ONLY THE FUTURE. IT’S THE ONLY FUTURE!
        </span>
        <span className="starsk-link">starsk.pro</span>
      </div>
      <div className="text-content-bottom">
        <span className="statement-text-bottom">
          CREATE YOUR NEXT <TempText body={tempText} />
          PROJECT WITH STRSK.PRO
        </span>
      </div>
    </div>
  );
}

And here is a working example in CodeSandbox.

  •  Tags:  
  • Related