Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to prevent a component's state from "propagating" on to the next component in a slideshow

Given a list of sentences, display the first sentence along with a next button. When the next button is clicked display the next sentence, and so on.

While a sentence is displayed, the user should be allowed to highlight individual words by clicking on them. Clicking on a highlighted word "unhighlights" it.

My attempt is shown below (you can run it on StackBlitz: https://slideshow-problem.stackblitz.io/ as well as fork and edit it: https://stackblitz.com/edit/slideshow-problem).

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

If I highlight the first word of the first sentence and click next, the first word of every subsequent sentence is highlighted as well. Why is this happening when each word and sentence is encapsulated inside their respective components? How can I fix it so that highlighting words of a sentence don’t affect the next sentences?

function Slideshow(props: { sentences: string[]; }) {
  const [currentSlideIndex, setCurrentSlideIndex] = useState(0);

  if (currentSlideIndex >= props.sentences.length) {
    return <div>Over.</div>;
  }

  return (
    <div>
      <ProblemComponentController
        sentence={props.sentences[currentSlideIndex]}
      />
      <button onClick={() => setCurrentSlideIndex(currentSlideIndex + 1)}>
        Next
      </button>
    </div>
  );
}
function ProblemComponentController(props: { sentence: string; }) {
  const words = props.sentence.split(' ');

  return (
    <p>
      {words.map((w, i) => (
        <span key={i}>
          <ProblemComponent word={w} />{' '}
        </span>
      ))}
    </p>
  );
}
function ProblemComponent(props: { word: string; }) {
  const [isHighlighted, setIsHighlighted] = useState(false);

  return (
    <span
      onClick={() => setIsHighlighted(!isHighlighted)}
      className={isHighlighted ? 'highlight' : ''}
    >
      {props.word}
    </span>
  );
}

>Solution :

You need to add key for the ProblemComponentController to make the component re-initialize.

    <div>
  <ProblemComponentController
    key={currentSlideIndex}
    sentence={props.sentences[currentSlideIndex]}
  />
  <button onClick={() => setCurrentSlideIndex(currentSlideIndex + 1)}>
    Next
  </button>
</div>

This is working example.
https://stackblitz.com/edit/slideshow-problem-is6anx?file=Slideshow.tsx

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading