I'm a ReactJS notive and while related questions on this topic have been asked, but I couldn't find the answer I'm looking for.
In ReactJS, I have two state variables. When one changes (let's call it A), I want the other (B) to change. My code currently does this correctly; when I drop breakpoints or log to console, B changes correctly when A changes. However, React does not render the updated B until A changes again. What is the cause, and what is the right React pattern to ensure B renders?
Snippets of my code (happy to answer more)
This is my variable A:
  const [prompt, setPrompt] = useState(params.prompt);
This is my variable B:
  let defaultPromptsResultsArray = [{
    isLoading: true,
    prompt: params.prompt,
    counter: 0,
    URIs: [default_uri]
  }]
  const [promptsResultsArray, setPromptsResultsArray] = useState(defaultPromptsResultsArray);
This is the useEffect that depends on prompt (my state variable A):
  useEffect(() => {
    // Take 0 for the newest prompt.
    const newBackendEventSource = new EventSource(
      url,
      {withCredentials: false})
    console.log('SSE created!');
    newBackendEventSource.addEventListener('open', () => {
      console.log('SSE opened!');
    });
    newBackendEventSource.addEventListener('error', (e) => {
      console.log('SSE error!');
      if (newBackendEventSource.readyState === EventSource.CLOSED) {
        // Connection was closed.
        console.log('SSE readyState is CLOSED')
      }
      console.error('Error: ',  e);
    });
    newBackendEventSource.addEventListener('close', (e) => {
      console.log('SSE closed!');
      const data = JSON.parse(e.data);
      console.log("close data: ", data);
      newBackendEventSource.close();
    });
    newBackendEventSource.addEventListener('message', (e) => {
      const data = JSON.parse(e.data);
      console.log("message data: ", data);
      // Use React Updater function to prevent race condition.
      // See https://stackoverflow.com/a/26254086/4570472
      setPromptsResultsArray((prevPromptsResultsArray) => {
        // Since we preprend new results, we need to compute the right index from
        // the counter with the equation: length - counter - 1.
        // e.g., For counter 2 of a length 3 array, we want index 0.
        // e.g., For counter 2 of a length 4 array, we want index 1.
        // e.g., For counter 3 of a length 7 array, we want index 4.
        // Recall, the counter uses 0-based indexing.
        const index = prevPromptsResultsArray.length - data.counter - 1
        prevPromptsResultsArray[index] = {
          isLoading: false,
          prompt: prevPromptsResultsArray[index].prompt,
          counter: prevPromptsResultsArray[index].counter,
          URIs: [data.uri]}
        return prevPromptsResultsArray
      });
    });
    // Add new backend event source to state for persistence.
    setBackendEventSources(backendEventSources => [
      newBackendEventSource,
      ...backendEventSources])
  }, [prompt]);
This is where my promptsResultsArray is used in the DOM:
          {promptsResultsArray.map((promptResults) => {
            const promptResultsKey = [promptResults.prompt, promptResults.counter].join("_");
            return (
              // Add a fragment ( a fake div ) so we can return 2 elements.
              <Fragment key={promptResultsKey}>
                <p key={`${promptResultsKey}_p1`}>Prompt: {promptResults.prompt}</p>
                {/* Creating keys from multiple values: https://stackoverflow.com/a/40425845/4570472*/}
                <ImageList cols={1} key={promptResultsKey}>
                  {promptResults.URIs.map((URI) => (
                    // Refactor to give each URI its own unique integer ID.
                    <ImageListItem key={[promptResults.prompt, promptResults.counter, 0].join("_")}>
                      <img
                        src={URI}
                        alt={promptResults.prompt}
                        style={{height: 260, width: 1034}}
                      />
                    </ImageListItem>
                  ))}
                </ImageList>
              </Fragment>
            )
          })}
promptsResultsArray is only updated when prompt is updated. Why? How do I ensure promptsResultsArray is also updated when changed by the SSE?
