0

Replacing the phrase - based on start and end index - by visibleText.

The problem - there is multiple phrases(each phrase changing per iteration) . So the value of transformedText is not refreshing by setTransformedText hook.

How to have changed transformedText - after setTransformedText - in each iteration?

for(const i in phrasesByCategory){

  const startIndex = phrasesByCategory[i].start_char;
  const endIndex = phrasesByCategory[i].end_char;
  const hiddenText = transformedText.substring(startIndex, endIndex);
  const visibleText = text.substring(startIndex, endIndex)

  const replacedPhrase  = replaceAt(transformedText, hiddenText, visibleText, startIndex, endIndex)

  setTransformedText(replacedPhrase)
}

The hook is string:

  const [transformedText, setTransformedText] = useState("")

It's replace the first iteration:

  const makeVisible = (phrasesByCategory) => {

    let currentText = transformedText
    setTransformedText((transformedText)=> {
      for(const i in phrasesByCategory){
        const startIndex = phrasesByCategory[i].start_char;
        const endIndex = phrasesByCategory[i].end_char;
        const hiddenText = transformedText.substring(startIndex, endIndex);
        const visibleText = text.substring(startIndex, endIndex);
        const replacedPhrase  = replaceAt(transformedText, hiddenText, visibleText, startIndex, endIndex)
        currentText = replacedPhrase
      }
      return currentText;
  })
}

Edit current solution - which finally anonymyse and unanomyse that phrases:

  const anonymyseByCategory = (phrasesByCategory, visible) => {
    const textArray = [transformedText];
    for (const i in phrasesByCategory) {
      const startIndex = phrasesByCategory[i].start_char;
      const endIndex = phrasesByCategory[i].end_char;
      let hiddenText = visible
        ? textArray[i].substring(startIndex, endIndex)
        : textArray[i].substring(startIndex, endIndex).replace(textArray[i].substring(startIndex, endIndex), 'X'.repeat(textArray[i].substring(startIndex, endIndex).length))
      const visibleText = text.substring(startIndex, endIndex);
      const sentenceWithReplacedPhrases = visible
        ? replaceAt(textArray[i], hiddenText, visibleText, startIndex, endIndex)
        : replaceAt(textArray[i], visibleText, hiddenText, startIndex, endIndex)
      textArray.push(sentenceWithReplacedPhrases)
      setTransformedText(sentenceWithReplacedPhrases);
    }
  }
skyboyer
  • 22,209
  • 7
  • 57
  • 64
Piotr Żak
  • 2,046
  • 5
  • 18
  • 30
  • Is your state property an array ? Please post your `useState` line. – Nice Books Oct 01 '21 at 18:26
  • sure - it just string. - the logic with replacing working - but in 2 iterations - the second one replace the first changed phrase - so only the last iteration have replaced string. – Piotr Żak Oct 01 '21 at 18:28
  • transformedText is sentence -> and each iteration changing one word in that sentence. – Piotr Żak Oct 01 '21 at 18:31

1 Answers1

1

I guess you have something like:

let [transformedText, setTransformedText] = useState('Hello World');

Since you are using the previous value of a state property (transformedText) in order to update it, you have to call your state property setter (setTransformedText) with a callback.

setTransformedText((transformedText)=> {
    var hiddenText = ...;
    var visibleText = ...;
    var replacedPhrase = replaceAt(...);
    return replacedPhrase;
});

This is due to the fact that, state updates may be asynchronous in React.

Nice Books
  • 1,675
  • 2
  • 17
  • 21