Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warnings in strict mode #13394

Closed
topheman opened this issue Oct 26, 2018 · 73 comments · Fixed by #16283
Closed

Warnings in strict mode #13394

topheman opened this issue Oct 26, 2018 · 73 comments · Fixed by #16283
Labels
priority: important This change can make a difference umbrella For grouping multiple issues to provide a holistic view
Milestone

Comments

@topheman
Copy link
Contributor

topheman commented Oct 26, 2018

EDIT: For the developers that feel adventurous, they can try:

import {
- createMuiTheme,
+ unstable_createMuiStrictModeTheme as createMuiTheme,
  darken,
} from '@material-ui/core/styles';

It's available since #20523, v4.9.11, our intended version for v5. You can find the documentation at https://material-ui.com/customization/theming/#unstable-createmuistrictmodetheme-options-args-theme.


I am playing with Suspense on my project topheman/react-fiber-experiments. I have the following warnings in development:

Warning: Legacy context API has been detected within a strict-mode tree: 

Please update the following components: MuiThemeProvider, WithStyles(AppBar), WithStyles(ButtonBase), WithStyles(Card), WithStyles(CardContent), WithStyles(CssBaseline), WithStyles(Drawer), WithStyles(Footer), WithStyles(Header), WithStyles(HomeContainer), WithStyles(IconButton), WithStyles(MainDrawer), WithStyles(MainLayout), WithStyles(Modal), WithStyles(Paper), WithStyles(SvgIcon), WithStyles(Toolbar), WithStyles(Typography)

Learn more about this warning here:
https://fb.me/react-strict-mode-warnings
Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of ButtonBase which is inside StrictMode. Instead, add a ref directly to the element you want to reference.

    in button (created by ButtonBase)
    in ButtonBase (created by WithStyles(ButtonBase))
    in WithStyles(ButtonBase) (created by IconButton)
    in IconButton (created by WithStyles(IconButton))
    in WithStyles(IconButton) (at Header.js:76)
    in div (created by Toolbar)
    in Toolbar (created by WithStyles(Toolbar))
    in WithStyles(Toolbar) (at Header.js:75)
    in header (created by Paper)
    in Paper (created by WithStyles(Paper))
    in WithStyles(Paper) (created by AppBar)
    in AppBar (created by WithStyles(AppBar))
    in WithStyles(AppBar) (at Header.js:74)

Learn more about using refs safely here:
https://fb.me/react-strict-mode-find-node

The Suspense part (asynchronous fetching, placeholders ...) works ok out of strict mode - check the demo.

Though, the async render part (time slicing) may need strict mode (check the link bellow). This is something to dig into now, people will soon be trying alphas of Suspense and a new major version of react will come in a few months.

Resource to read

Related: Migrate from findDOMNode to refs

Your Environment

Tech Version
Material-UI v3.1.2
React v16.6.0 - custom build from this commit
Browser Chrome

More infos:

@eps1lon
Copy link
Member

eps1lon commented Oct 26, 2018

We can't get rid of findDOMNode in many cases as I pointed out previously: #13221 (comment)

Is there currently a way to check from a component if it is in StrictMode? That way we could avoid findDOMNode and somehow communicate to users that their components should properly forward their refs.

The context API rewrite should hopefully not cause any breakage but I'm not very familiar with our theming approach.

@topheman
Copy link
Contributor Author

Is there currently a way to check from a component if it is in StrictMode? That way we could avoid findDOMNode and somehow communicate to users that their components should properly forward their refs.

It seems that you need to have access to the current fiber in process : https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberBeginWork.js#L946-L948 though, this will be a common need for library authors.

@eps1lon
Copy link
Member

eps1lon commented Oct 26, 2018

I think that line is about context.

So I looked at the code of findDOMNode and did some testing and it turns out that React does not warn if you pass a dom element element type which is perfect for us. We can still use findDOMNode but test our tree in strict mode to be ready for Supsense StrictMode.

Example: https://codesandbox.io/s/qko6n6vzjj

@topheman
Copy link
Contributor Author

Just to be clear, it currently works with Suspense (this is the Async rendering part which might pose problem - like Time Slicing).

Your example is perfect 👍- at least we know that there is an escape hatch anyway.

However, this means, that each time the user passes a component prop, he/she will have to create a new one with React.forwardRef before using it.

Example:

<Toolbar>
  <Button
    component={Link}
    to="/"
    title="Home"
  />
  <IconButton
    component={Link}
    to="/foo"
    title="Foo"
  />
  <Typography
    component={Link}
    to="/"
    title="Bar"
  >
    Bar
  </Typography>
</Toolbar>

@eps1lon
Copy link
Member

eps1lon commented Oct 26, 2018

@topheman Might be a good idea to add a note to the documentation where people can pass their own component and we use findDOMNode on their refs and require that those components forward their refs properly in the next major or so.

We could also issue deprecation warnings if findDOMNode(ref) !== ref but this won't provide useful error stacks unless we actually throw. I wish the warning package would include the component stack.

Also the react docs recommend using forwardRef with a new major because it could be considered breaking behavior (with which I agree) but we have to be careful not to introduce to many breaking changes in our next major because people might not be able to upgrade.

@gaearon
Copy link

gaearon commented Dec 4, 2018

React does not warn if you pass a dom element which is perfect for us.

If you pass a DOM element, why do you need findDOMNode at all? It will just give you that element back.

@eps1lon
Copy link
Member

eps1lon commented Dec 4, 2018

React does not warn if you pass a dom element which is perfect for us.

If you pass a DOM element, why do you need findDOMNode at all? It will just give you that element back.

@gaearon
We don't pass the DOM elements but the user. We interface the as prop in Button so that it accepts anything that can hold refs.

interface Props {
  as: React.ComponentClass | React.ForwardRefExoticComponent | string;
}
function Button({ as: Component }: Props) {
  // users in strict mode would be required to forward refs to the DOM node
  // while users in "loose" mode can simply pass in anything that can hold refs
  return <Component ref={ref => findDOMNode(ref)!.focus()} />
}

// valid
<Button as="div" />
<Button as={SomeClassComponent} />
<Button as={SomeComponentThatForwardsRefs} />
<Button as={ReactRouterLink} />
// invalid but was valid via findDOMNode(this) in the Button implemented as a class component
<Button as={() => <ReactRouterLink to="/somewhere" />} />

@eps1lon eps1lon mentioned this issue Feb 5, 2019
99 tasks
@eps1lon eps1lon modified the milestones: future, 16.8 React.StrictMode Mar 12, 2019
@eps1lon eps1lon added the umbrella For grouping multiple issues to provide a holistic view label Mar 12, 2019
@eps1lon
Copy link
Member

eps1lon commented Mar 12, 2019

Tracking progress here.
Test plan:

@oliviertassinari
Copy link
Member

oliviertassinari commented Jul 28, 2019

An update on our current progress.

We have solved most the issue in Material-UI. We dependent on reactjs/react-transition-group#429 to be 100% compliant.

@sibelius
Copy link

since with version mui has solved most strict issues?

@oliviertassinari
Copy link
Member

@sibelius v4.5.1 is a safe bet 😁.

WordlessEcho added a commit to WordlessEcho/Brambling-Note-FE that referenced this issue Jun 20, 2021
@oliviertassinari oliviertassinari moved this from Q2 2021 Apr - Jun to Q3 2021 Jul-Sep in MUI Core public roadmap Jul 3, 2021
@EddyVinck
Copy link

@topheman Do you know if this is still an issue in v5 beta?

@oliviertassinari
Copy link
Member

oliviertassinari commented Jul 22, 2021

Looking at the results of https://github.com/mui-org/material-ui/search?q=StrictModeViolation.

Capture d’écran 2021-07-23 à 01 51 47

It seems that we are done. The instances where it fails are related to the soon-to-be deprecated @material-ui/styles package. @eps1lon Is it accurate? Is there anything left to do before we can close?

@eps1lon
Copy link
Member

eps1lon commented Jul 23, 2021

Public documentation that these methods are neither StrictMode nor React 18 compatible is missing. Then we can close. For StrictMode issues in React 18 I would start a new issue.

@SangeetAgarwal

This comment has been minimized.

@SangeetAgarwal

This comment has been minimized.

@oliviertassinari

This comment has been minimized.

@eps1lon
Copy link
Member

eps1lon commented Aug 17, 2021

With the release of v5 (release candidate next week) all StrictMode related issues for React 17 (and current 18) will be fixed. For new StrictMode issues in React 18 we'll want to open a new issue (if they come up).

Happy to close this issue before its 3 year anniversary and thank you for your patience.

@deroude

This comment has been minimized.

@mui mui locked as resolved and limited conversation to collaborators Sep 26, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
priority: important This change can make a difference umbrella For grouping multiple issues to provide a holistic view
Projects
None yet
Development

Successfully merging a pull request may close this issue.