GithubHelp home page GithubHelp logo

Comments (17)

BryanChrisBrown avatar BryanChrisBrown commented on July 27, 2024 8

Also hitting this issue, safari version 17.1

from react.

Hyodori04 avatar Hyodori04 commented on July 27, 2024 1

If use dangerouslySetInnerHTML. It works

from react.

gaearon avatar gaearon commented on July 27, 2024

Would you mind turning this into two CodeSandbox'es? Thanks!

from react.

evanbernstein avatar evanbernstein commented on July 27, 2024

@gaearon I created this CodeSandbox with the code. Unfortunately, the issue does not reproduce in CodeSandbox. You can certainly view the code. Is there any chance you could test out the repo that I created on your machine?

Thanks.

from react.

evanbernstein avatar evanbernstein commented on July 27, 2024

@gaearon My best guess is that everything runs just a bit slower in CodeSandbox and thus the renders don't get skipped, at least on my Intel Mac. You are probably a much better expert than I am.

I did just try the CodeSandbox implementation on an m1 mac, and it was not reproducible there.

from react.

nicolawebdev avatar nicolawebdev commented on July 27, 2024

True, tested on my MacBook (M1 Pro) with Safari 16.5.

from react.

draysams avatar draysams commented on July 27, 2024

Test on MacBook (M2 Pro) with Safari 16.6. Can confirm I'm facing this issue as well.

from react.

evanbernstein avatar evanbernstein commented on July 27, 2024

With the release of macOS Sonoma imminent, I updates the packages in my linked project and tested in the latest Safari.

info Direct dependencies
├─ @types/[email protected]
├─ @types/[email protected]
└─ @types/[email protected]
info All dependencies
├─ @types/[email protected]
├─ @types/[email protected]
├─ @types/[email protected]
├─ @types/[email protected]
├─ @types/[email protected]
└─ [email protected]

With these updates this is still reproducible with Safari Version 17.0 (19616.1.27.111.16).

from react.

brunofin avatar brunofin commented on July 27, 2024

we are also affected by this bug on nextjs and react 18.2.0

from react.

fabiancarlos avatar fabiancarlos commented on July 27, 2024

Its dont render nothing, cant find why... but, i fixed temporarly on Safari mobile, with my iPhone, opening:
Configuration > Safari > Advanced > Experimental Features > than activate all.

So, now renders, but, its just too absurd to ask for any user to do this.

from react.

timwuhaotian avatar timwuhaotian commented on July 27, 2024

Same happens for iOS, v11.2

from react.

ajbura avatar ajbura commented on July 27, 2024

It happens to me as well in safari.

But I think problem is with how batch state update breaks declarative set state notion.
For example

export enum AsyncStatus {
  Idle = 'idle',
  Loading = 'loading',
  Success = 'success',
  Error = 'error',
}

export type AsyncIdle = {
  status: AsyncStatus.Idle;
};

export type AsyncLoading = {
  status: AsyncStatus.Loading;
};

export type AsyncSuccess<D> = {
  status: AsyncStatus.Success;
  data: D;
};

export type AsyncError<E = unknown> = {
  status: AsyncStatus.Error;
  error: E;
};

export type AsyncState<D, E = unknown> = AsyncIdle | AsyncLoading | AsyncSuccess<D> | AsyncError<E>;

AsyncState is state of my useAsyncCallback hook. so in safari fetch request resolves so fast(~8ms when browser has it's result cached) that react batch AsyncLoading and AsyncSuccess state, and in component A where this hook used, state update from prev AsyncSuccess to new AsyncSuccess state.

So in that component A i render a child only when result is AsyncSuccess and based on that contract that child component should unmount and re-mount when the fetch request happen as I explicitly declare AyncLoading before fetch happen and AsyncSuccess got set.

And because react skip that state, my child component (screenshot below) doesn't go though mount unmount cycle.
Child component:
image

And in my child component code which depend on the mount-unmount cycle doesn't run which result in in missing UI update:

if (state.status === AsyncStatus.Idle) load();

Now i can run that load() callback in useEffect to fix this or wrap the set AyncLoading state in flushSync

but issue is actually with the how batch update breaks react declarative nature as i explicitly declare the state to be updated. I think immediate update is the correct declarative nature and batch update have to be optional and declarative with API like:

batchUpdates(() => {
//multiple set state calls
})

For more: React provides a declarative way to manipulate the UI: https://react.dev/learn/reacting-to-input-with-state#how-declarative-ui-compares-to-imperative

from react.

ajbura avatar ajbura commented on July 27, 2024

@evanbernstein same ^^^ is happening with you

import React from "react";

interface LogProp {
  message: string;
  number: number;
  title: string;
  subtitle: string;
}
export const LogWithState: React.FC<{ log: LogProp }> = ({ log }) => {
  const { message, number, title, subtitle } = log;
  const [prevMessages, setMessages] = React.useState<string[]>([]);
  const [prevNumber, setNumber] = React.useState(-1);
  if (number !== prevNumber) {
    const newMessages = prevMessages.concat(message);
    setMessages(newMessages);
    setNumber(number);
  }
  return (
    <>
      <h2>{title}</h2>
      <h3>{subtitle}</h3>
      <div>
        {prevMessages.map((message, i) => (
          <div key={i}>{message}</div>
        ))}
      </div>
    </>
  );
};

your setMessages(newMessages) are getting ignored by batchUpdate and it only set the last call with prevMessage and last message

from react.

ajbura avatar ajbura commented on July 27, 2024

Now i can run that load() callback in useEffect to fix this or wrap the set AyncLoading state in flushSync

i was wrong about calling load() in useEffect, I mean this is something I should do i.e calling load again if one of load dependencies changes. but that batch update makes the data problem more worse as now context data from component A and context data produces by child AuthFlowLoader component, in combination serve as wrong data for react tree down the line until that load function resolves to new data.

So, overall I have to do:

flushSync(() => {
  setState({
    status: AsyncStatus.Loading,
  });
});

before resolving async callback.
And API flushSync doesn't make sense to me much, because I have to tell it to do what it suppose to do at first place, and now i am more concern about possible happening of situation like this through out the whole app.

Edited:

Warning: flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.

queueMicrotask(() => {
  flushSync(() => {
    setState({
      status: AsyncStatus.Loading,
    });
  });
});

👀

from react.

navyblue21 avatar navyblue21 commented on July 27, 2024

Same happens for iOS v14.4, React 18.2.0

from react.

github-actions avatar github-actions commented on July 27, 2024

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

from react.

evanbernstein avatar evanbernstein commented on July 27, 2024

bump

from react.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.