Material-ui: Peringatan: useLayoutEffect tidak melakukan apa-apa di server, karena efeknya tidak bisa […]

Dibuat pada 23 Mei 2019  ·  53Komentar  ·  Sumber: mui-org/material-ui

Versi 4 dari <ButtonBase> sekarang menggabungkan useLayoutEffect() dalam kode src di sini . Ini tidak ada di versi 3.

Saya memahami kebutuhan untuk itu namun setiap tes lelucon untuk komponen yang memiliki <Button> di dalamnya sekarang menghasilkan peringatan konsol seperti ini:

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://fb.me/react-uselayouteffect-ssr for common fixes.
          in ForwardRef(ButtonBase)
          in WithStyles(ForwardRef(ButtonBase))
          in ForwardRef(Button)
          in WithStyles(ForwardRef(Button)) (at ButtonWithIcon/index.tsx:57)
          in Layout (at ButtonWithIcon/index.tsx:26)
          in ButtonWithIcon (at OAuthButton/index.tsx:58)
          in Layout (at OAuthButton/index.tsx:21)
          in OAuthButton (at OAuthSignUp.tsx:221)
          in div (at OAuthSignUp.tsx:200)
          in Layout (at OAuthSignUp.tsx:138)
          in OAuthSignUp (at OAuthSignUp.unit.test.tsx:60)
          in Context.Provider
          in ThemeProvider (at testProviders.tsx:29)
          in Context.Provider (at store.tsx:36)
          in Provider (at testProviders.tsx:28)
          in Providers (at OAuthSignUp.unit.test.tsx:59)

Tes masih lulus karena ini hanya peringatan, tetapi adakah cara untuk mencegah pesan peringatan ini muncul? Saya benar-benar bahkan tidak dapat melihat semua peringatan di terminal saya karena ada begitu banyak.

bug 🐛 external dependency

Komentar yang paling membantu

@oliviertassinari ya, benar-benar. Itu akan bagus!

Semua 53 komentar

Ini berarti penyiapan pengujian Anda memiliki DOM saat Anda menggunakan rendering sisi-server. Saya tidak berpikir ReactDOM.renderToStaticMarkup memiliki kasus penggunaan di browser. Saya yakin Anda bisa memberi tahu lelucon untuk menjalankan tes di lingkungan tertentu. Untuk pengujian SSR Anda, Anda harus menjalankan node bukan jsdom .


Edit oleh @oliviertassinari

Apakah itu akan berhasil, dalam kasus Anda dengan? (dari reaksi ):


// React currently throws a warning when using useLayoutEffect on the server.
// To get around it, we can conditionally useEffect on the server (no-op) and
// useLayoutEffect in the browser.
const canUseDOM: boolean = !!(
  typeof window !== 'undefined' &&
  typeof window.document !== 'undefined' &&
  typeof window.document.createElement !== 'undefined'
);

const useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect;

Saya menggunakan Next.js dan saya mendapatkan peringatan yang sama tetapi di Konsol Chrome saat halaman saya dimuat.
Padahal saya sudah update ke contoh (https://github.com/mui-org/material-ui/tree/master/examples/nextjs)

Kode saya cukup besar sehingga akan membutuhkan sedikit waktu untuk memberikan reproduksi, tetapi hanya untuk mengonfirmasi bahwa saya juga menggunakan Next.js dan pengujian saya dijalankan di jsdom (dengan jest dan react-testing-library), dalang (dengan jsdom-screenshot) dan ReactDOM.renderToStaticMarkup (dengan jest-ax). Saya belum menentukan penyebab masalah ini.

Saya menggunakan Next.js dan saya mendapatkan peringatan yang sama tetapi di Konsol Chrome saat halaman saya dimuat.
Padahal saya sudah update ke contoh ( / example / nextjs @ master )

Membuat salinan baru dari contoh kami tidak mencatat peringatan apa pun untuk saya. Jika Anda memiliki beberapa pengaturan kustom, harap sertakan contoh lengkap yang dapat direproduksi. Hal yang sama berlaku untuk @TidyIQ. Masalahnya bergantung pada lingkungan spesifik Anda. Saya kira Anda mendapatkan peringatan yang sama menggunakan versi terbaru react-redux.

@ eps1lon Saya menemukan sumber masalah dalam kasus saya.
Ini penggunaan next/link bukan @material-ui/core/Link

import Link from "next/link"

<Link href="/about">
  <Fab>
    <AddIcon />
  </Fab>
</Link>

<Link href='/contact' color='inherit' className={classes.link}>
    <ListItem button>
      <ListItemIcon>
        <ContactsIcon />
      </ListItemIcon>
      <ListItemText primary='Contatos' />
    </ListItem>
 </Link>

Ketika saya mengklik salah satu link ini, halaman baru dimuat dan peringatan ditampilkan di DevTools

Hanya mengubah impor ke @material-ui/core/Link menyelesaikan masalah.

AKHIRNYA, saya bisa mereproduksi kesalahan! 😅
Dan ternyata, masalahnya adalah ketika Anda memasang next-with-apollo ke _app.js

Jika saya menggunakan contoh untuk Berikutnya dan Apollo (https://github.com/zeit/next.js/tree/master/examples/with-apollo) masalah tidak terjadi tetapi saya kehilangan beberapa fungsionalitas yang baik dari next-with-apollo penawaran

Langkah-langkah untuk melakukannya:

Gandakan contoh MUI dengan NextJS (https://github.com/mui-org/material-ui/tree/master/examples/nextjs)

curl https://codeload.github.com/mui-org/material-ui/tar.gz/master | tar -xz --strip=2  material-ui-master/examples/nextjs
cd nextjs
npm i
npm i next-with-apollo apollo-boost graphql

Buat HOC yang membuat Klien Apollo (next-with-apollo.js)

import withApollo from 'next-with-apollo';
import ApolloClient from 'apollo-boost';

export default withApollo(
  ({ headers }) =>
    new ApolloClient({
      uri: 'https://localhost:4000',
      request: operation => {
        operation.setContext({
          fetchOptions: {
            credentials: 'include',
          },
          headers,
        });
      },
    })
);

Lampirkan HOC di _app.js

import withApollo from '../src/next-with-apollo';
...
export default withApollo(MyApp);

Tambahkan beberapa Tombol ke halaman mana pun!
Saat Anda mengklik link untuk pergi ke halaman yang memiliki Tombol tersebut, 11 peringatan muncul di DevTools

index.js:1 Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://fb.me/react-uselayouteffect-ssr for common fixes.
    in NoSsr
    in button
    in ForwardRef(ButtonBase)
    in WithStyles(ForwardRef(ButtonBase))
    in ForwardRef(Button)
    in WithStyles(ForwardRef(Button)) (at pages/index.js:29)
    in div
    in Styled(MuiBox) (at pages/index.js:25)
    in div
    in ForwardRef(Container)
    in WithStyles(ForwardRef(Container)) (at pages/index.js:24)
    in Index (at _app.js:29)
    in Context.Provider
    in ThemeProvider (at _app.js:26)
    in Container (at _app.js:22)
    in MyApp
    in RenderPromisesProvider
console.<computed> @ index.js:1
warningWithoutStack @ react-dom-server.browser.development.js:104
warning @ react-dom-server.browser.development.js:290
useLayoutEffect @ react-dom-server.browser.development.js:1215
useLayoutEffect @ react.development.js:1482
NoSsr @ NoSsr.js:28
processChild @ react-dom-server.browser.development.js:2887
resolve @ react-dom-server.browser.development.js:2811
render @ react-dom-server.browser.development.js:3201
read @ react-dom-server.browser.development.js:3160
renderToStaticMarkup @ react-dom-server.browser.development.js:3660
process @ react-apollo.esm.js:1038
Promise.then (async)
getMarkupFromTree @ react-apollo.esm.js:1043
getDataFromTree @ react-apollo.esm.js:1009
(anonymous) @ withApollo.js:128
step @ withApollo.js:56
(anonymous) @ withApollo.js:37
fulfilled @ withApollo.js:28
Promise.then (async)
step @ withApollo.js:30
(anonymous) @ withApollo.js:31
push../node_modules/next-with-apollo/lib/withApollo.js.__awaiter @ withApollo.js:27
_a.getInitialProps @ withApollo.js:102
_callee$ @ utils.js:33
tryCatch @ runtime.js:62
invoke @ runtime.js:288
prototype.<computed> @ runtime.js:114
asyncGeneratorStep @ asyncToGenerator.js:5
_next @ asyncToGenerator.js:27
(anonymous) @ asyncToGenerator.js:34
F @ _export.js:36
(anonymous) @ asyncToGenerator.js:23
loadGetInitialProps @ utils.js:33
_callee2$ @ router.js:373
tryCatch @ runtime.js:62
invoke @ runtime.js:288
prototype.<computed> @ runtime.js:114
asyncGeneratorStep @ asyncToGenerator.js:5
_next @ asyncToGenerator.js:27
(anonymous) @ asyncToGenerator.js:34
F @ _export.js:36
(anonymous) @ asyncToGenerator.js:23
getInitialProps @ router.js:383
(anonymous) @ router.js:245
F @ _export.js:36
(anonymous) @ router.js:243
Promise.then (async)
getRouteInfo @ router.js:235
(anonymous) @ router.js:187
F @ _export.js:36
change @ router.js:149
push @ router.js:143
SingletonRouter.<computed> @ router.js:71
Link._this.linkClicked @ link.js:125
onClick @ link.js:193
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:270
executeDispatch @ react-dom.development.js:561
executeDispatchesInOrder @ react-dom.development.js:583
executeDispatchesAndRelease @ react-dom.development.js:680
executeDispatchesAndReleaseTopLevel @ react-dom.development.js:688
forEachAccumulated @ react-dom.development.js:662
runEventsInBatch @ react-dom.development.js:816
runExtractedEventsInBatch @ react-dom.development.js:824
handleTopLevel @ react-dom.development.js:4826
batchedUpdates$1 @ react-dom.development.js:20439
batchedUpdates @ react-dom.development.js:2151
dispatchEvent @ react-dom.development.js:4905
(anonymous) @ react-dom.development.js:20490
unstable_runWithPriority @ scheduler.development.js:255
interactiveUpdates$1 @ react-dom.development.js:20489
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882

Pasti itu. Saya juga menggunakan Apollo Client.

Terima kasih atas tegurannya. Akan memeriksa apakah ini masih terjadi menggunakan reduxjs / react-redux # 1283.

@ralvs Rep tidak dimulai. Bisakah Anda membuat repositori yang dapat digandakan atau memeriksa https://github.com/eps1lon/mui-buttonbase-uselayout-repro dan melihat apa yang hilang? Ikuti langkah Anda (ganti npm dengan benang sekalipun). Harus menginstal react-apollo (tidak dapat menemukan modul) setelah itu saya mendapatkan [ error ] TypeError: Cannot set property default of #<Object> which has only a getter ketika menjalankan yarn dev

@ eps1lon Jika saya tidak salah, Anda mengalami masalah berikut: https://github.com/apollographql/apollo-client/issues/4843

Solusi saat ini tampaknya kembali ke v0.3.1 atau mengimpor klien dari apollo-boost / lib / index

Terima kasih telah mengerjakan ini :-)

@PedeLa Terima kasih atas tipnya. Bisa membuatnya bekerja:

$ git clone https://github.com/eps1lon/mui-buttonbase-uselayout-repro.git
$ cd mui-buttonbase-uselayout-repro
$ yarn
$ yarn dev
# goto localhost:3000/about

tetapi saya tidak dapat mereproduksi kesalahan apa pun. Baik browser maupun konsol terminal tidak mencatat peringatan apa pun yang terkait dengan useLayoutEffect .

Aneh, saya mengikuti langkah Anda dengan tepat dan saya mendapatkan:
image
Edit: Hanya peringatan konsol browser, terminal tidak menampilkan peringatan apa pun

Saya baru saja melakukan hal yang sama.
Menggunakan Chrome Versi 74.0.3729.169 (Versi Resmi) (64-bit)
Di MacOS Mojave v10.14.5

Screen Shot 2019-05-31 at 08 15 25

Saya juga membuka terbitan next-with-apollo repo: # 60

Dapatkah seseorang mereproduksi ini pada distribusi linux? Mungkin apollo mengejek beberapa bagian DOM di server hanya di mac?

Saya dapat mereproduksi kesalahan persis ini pada distribusi berbasis Ubuntu.

Saya dapat mereproduksi di MacOS 10.14.5.

Oke, menemukannya. Kami dapat menutup masalah ini. Anda dapat mereproduksi masalah tanpa Material-UI:

import React from "react";

const useEnhancedEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;

function MadeWithLove() {
  useEnhancedEffect(() => {});

  return (
    <span>
      {"Built with love by the "}
    </span>
  );
}

Masalahnya adalah bahwa next-with-apollo melintasi pohon, secara default, di browser dengan API sisi server:

Saya telah menggunakan Apollo secara ekstensif selama lebih dari satu tahun di onepixel.com. Saya akan berhati-hati dengannya, ini bisa lambat dalam skala, itu adalah hambatan kami n ° 1 dari perspektif kinerja (graphql + apollo client). Saya yakin Anda tidak perlu melintasi pohon React dengan API sisi server pada klien saat berpindah rute. Anda dapat memiliki loader atau logika getInitialProps terpusat sebagai gantinya.

@oliviertassinari terima kasih telah menemukan akar
Namun, setelah saya menyetel withApollo(..., { getDataFromTree: 'never' }) dan new ApolloClient({ ssrMode: false, ... }) , saya masih melihat pesan peringatan.
Ada hit untukku?

Maaf, saya tidak bisa membantu lebih banyak. Saya tutup. Saya bisa bertanya di https://github.com/lfades/next-with-apollo/issues/60.

@ivawzh Saya telah mencobanya pada reproduksi yang disediakan oleh @ eps1lon , ini memecahkan masalah:

diff --git a/src/next-with-apollo.js b/src/next-with-apollo.js
index b0655aa..ba5d3ee 100644
--- a/src/next-with-apollo.js
+++ b/src/next-with-apollo.js
@@ -13,5 +13,5 @@ export default withApollo(
           headers
         });
       }
-    })
+    }), { getDataFromTree: 'never' }
 );

@oliviertassinari masalah ini bukan masalah apollo, Anda harus dapat membuat struktur komponen UI di server dan klien.

inilah artikel yang menggambarkan teknik ini:

https://medium.com/@alexandereardon/uselayouteffect -and-ssr-192986cdcf7a

masalah, dan masalah yang harus diselesaikan adalah material-ui harus memiliki useIsomorphicLayoutEffect mereka sendiri sehingga efeknya tetap berjalan di klien dan server.

@lifeiscontent Ini adalah teknik yang sama yang kami gunakan. Masalahnya adalah itu tidak berfungsi jika Anda menggunakan API SSR di browser.

@ eps1lon Saya menyadari sekarang masalah yang saya lihat adalah karena menggunakan versi yang lebih lama. Dalam proses peningkatan sekarang. 🤞

Btw Saya juga punya masalah ini (lelucon adalah spamming dengan peringatan ini), dan saya tidak menggunakan next.js atau next-with-apollo.
Hanya react / redux & cie dan material-ui (antara lain, tentu saja).

Apakah Anda pikir saya memiliki lib lain yang mengganggu?

@nsaubi Apakah window ditentukan dalam pengujian env Anda?

const jestConfig = { "testEnvironment": "jsdom", ...
@oliviertassinari Conf jest saya adalah jsdom, jadi saya yakin ya itu.

Dan btw kami tidak menggunakan SSR sama sekali. Dan basis kode kami masih "16.5ish", karena saya baru saja memperbarui dependensi dan karenanya kami tidak menggunakan hook untuk saat ini.

Sunting: Baru saja menemukan ini (dan saya pikir ini terkait, akan menguji): https://github.com/facebook/react/issues/14927#issuecomment -515768079

Juga mendapat masalah ini. Saya memiliki aplikasi isomorfik, dan memiliki objek "jendela" dalam lingkup global untuk server, karena server tersebut menggunakan useLayoutEffect dan saya memiliki sejumlah besar peringatan di konsol server.
Memeriksa apakah jendela ditentukan tidak cukup. Harap tambahkan pemeriksaan setidaknya untuk "window.document":
https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/utils/useEventCallback.js

Saya memiliki aplikasi isomorfik, dan memiliki objek "jendela" dalam lingkup global untuk server

Mengapa Anda memiliki jendela dalam lingkup global untuk server? Saya ragu aplikasi isomorfik adalah jawaban yang bagus. Apakah ini untuk mengatasi ketergantungan yang rusak? Komponen NoSr kami dapat membantu.

Ya, tapi bagaimanapun itu bisa berguna dalam kasus lain. Bagaimanapun karena masalah ini terjadi dalam keadaan yang berbeda, saya pikir pemeriksaan sederhana untuk keberadaan jendela tidak pemeriksaan yang tepat untuk menentukan apakah server atau klien ini. Saya pikir mui seharusnya tidak memberi tahu pengguna untuk tidak memiliki "jendela" dalam lingkup global.
Misalnya 'react-urgen' bekerja dengan window.navigator.userAgent , dan jika kita ingin menebak perangkat klien dengan di server, kita tidak dapat melakukannya karena tidak ada window.navigator.userAgent , jadi pengaturan itu akan menyelesaikan masalah isu.

@ndeviant Anda dapat menggunakan https://material-ui.com/components/use-media-query/ , Anda tidak perlu "mencemari" cakupan global dengan objek jendela.

Sepertinya konteks React harus digunakan di sini: https://github.com/medipass/react-ugent/blob/d6c68c367316cedf2598b40909c241fcb6b96c81/src/index.js#L44. Ini tidak mendukung permintaan bersamaan. Itu hanya dapat bekerja secara sinkron, satu permintaan sisi server setelah yang lain.

Saya senang telah menemukan keberadaan ua-parser-js . Saya akan memperbarui dokumentasi ssr dari useMediaQuery dengannya, ini dapat membantu ketika petunjuk klien tidak tersedia.

Saya setuju dengan Anda, dan terima kasih atas bantuan Anda.
Tapi apa pendapat Anda tentang ini:

Saya pikir pemeriksaan sederhana untuk keberadaan jendela bukanlah pemeriksaan yang tepat untuk menentukan apakah server atau klien ini. Saya pikir mui seharusnya tidak memberi tahu pengguna untuk tidak memiliki "jendela" dalam lingkup global.

Saya membutuhkan banyak waktu untuk mengetahui bahwa alasan peringatan ini adalah karena material-ui tidak mengenali server atau klien ini dengan benar. Dan itu didasarkan pada keberadaan objek jendela

Tapi apa pendapat Anda tentang ini:

@ndeviant Apakah kami memiliki pilihan yang lebih baik?

Mungkin sesuatu seperti ini:

function isServer() {
  return  typeof window === 'undefined' ||
    (typeof global !== 'undefined' &&
      (!window.global || window.global !== global));
}

Diedit: menambahkan kemungkinan untuk memiliki global.window.global prop, untuk menghindari konflik.

@ndeviant Maaf, ini adalah undangan untuk membaca seluruh utas. @ eps1lon telah menyarankan pendekatan yang bagus di https://github.com/mui-org/material-ui/issues/15798#issuecomment -497619267.

Apakah itu akan berhasil, dalam kasus Anda dengan? (dari reaksi ):


// React currently throws a warning when using useLayoutEffect on the server.
// To get around it, we can conditionally useEffect on the server (no-op) and
// useLayoutEffect in the browser.
const canUseDOM: boolean = !!(
  typeof window !== 'undefined' &&
  typeof window.document !== 'undefined' &&
  typeof window.document.createElement !== 'undefined'
);

const useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect;

@ eps1lon Haruskah kita membuka kembali dan menerapkan solusi berbasis canUseDOM (dari basis kode React)? Kami memiliki 7 orang berbeda yang berinteraksi dengan masalah ini dalam 3 bulan. Ini tidak banyak, sejauh ini, tampaknya masalah yang mendasari muncul di basis kode orang. Saya senang dengan cara apa pun dan saya cenderung belum melakukan apa pun.

Perhatikan bahwa ini lebih luas untuk efek tata letak, kami menjalankan typeof window !== 'undefined' di beberapa tempat lain.

@oliviertassinari ya, benar-benar. Itu akan bagus!

@ndeviant Kemajuan apa yang perlu dilakukan? Sejauh ini Anda adalah satu-satunya, yang kami ketahui, yang akan mendapat manfaat dari https://github.com/mui-org/material-ui/issues/15798#issuecomment -528311534 dan bahkan kemudian, kasus penggunaannya adalah, seperti Sejauh yang saya mengerti, tidak valid (harus menggunakan konteks bukan global untuk menyebarkan agen pengguna).

Saya menjelaskan hanya satu kasus ketika jendela di server dapat berguna. Pembuat masalah awal memiliki 9 "Jempol" tentang hal ini, sepertinya orang-orang terus mengalami masalah ini berulang kali, dengan keadaan yang berbeda (tes env, bukan deps ideal, dll.). Masalah saya yang sebenarnya adalah, saya mendapatkan proyek, yang ditulis sebelum saya, yang menggunakan jendela di server, dan pergi dan melakukan refactor semua yang menggunakan logika ini, hanya untuk menghilangkan peringatan yang mengganggu saya tidak mampu.

Untuk menyimpulkan apa yang saya katakan sebelumnya:

  1. Haruskah 'react-urgen' bekerja dengan window.navigator.userAgent , alih-alih konteks? Tidak, pasti.
  2. Haruskah pengguna menetapkan objek 'window' di server? Mungkin tidak.
  3. Apakah ini tanggung jawab 'material-ui', untuk mengatakan apakah dia bisa mendefinisikan 'jendela' di server? Tidak. Serahkan saja pada linters atau node itu sendiri, terutama peringatan di konsol tidak mengatakan sesuatu yang berguna.

React tidak bertanggung jawab untuk mengatakan, bahwa Anda seharusnya tidak mendefinisikan 'window' di server, dan memeriksa keberadaan dom dengan benar.
Jadi menurut Anda ini bukan bug, tapi fitur?

Jadi menurut Anda ini bukan bug, tapi fitur?

Itu adalah sesuatu yang tidak bisa kita kendalikan. Sayangnya kami hanya memiliki useLayoutEffect untuk sesuatu yang perlu dijalankan selama komit. Sekarang react memperingatkan jika ia mendeteksi efek ini saat menggunakan ssr API karena ia mengasumsikan bahwa apa pun dalam efek tersebut memengaruhi tata letak. Dalam kasus kami tidak.

Sekarang kami menyelesaikan masalah ini dengan mengasumsikan bahwa api SSR digunakan di server dan api CSR digunakan di klien. Tetapi tidak ada yang mencegah Anda untuk menggunakan api SSR pada klien juga (atau lebih tepatnya di lingkungan dengan DOM) yang menghasilkan positif palsu ini.

Kami menyuarakan keprihatinan kami tentang peringatan ini kepada tim inti react tetapi tidak mendapat tanggapan apa pun. Pada titik ini kita tidak bisa berbuat apa-apa lagi.

Sejauh yang saya tahu, tidak ada cara untuk mengetahui apakah sebuah komponen dirender dengan api SSR atau api CSR. Jika ada maka kita bisa menyelesaikan masalah ini.

Untuk pengembang yang datang ke halaman ini. Jika Anda terpengaruh oleh masalah ini, berikan suara positif untuk masalah tersebut dan berikan reproduksi yang dapat kami lihat . Semakin banyak umpan balik, solusi terbaik yang dapat kami temukan. Terima kasih.

Halo, saya mereproduksi menggunakan fungsi render Enzyme.
Ini kotak pasir

Saya memiliki problema yang sama,

index.js: 1 Peringatan: useLayoutEffect tidak melakukan apa pun pada server, karena efeknya tidak dapat dikodekan ke dalam format keluaran perender server. Ini akan menyebabkan ketidakcocokan antara UI awal yang tidak terhidrasi dan UI yang dimaksudkan. Untuk menghindarinya, useLayoutEffect sebaiknya hanya digunakan dalam komponen yang dirender secara eksklusif pada klien. Lihat https://fb.me/react-uselayouteffect-ssr untuk perbaikan umum.
di NoSsr
di tombol
di ForwardRef (ButtonBase)

Kode.
export default props => { return <AppBar position='sticky'> <Toolbar> <IconButton color='inherit' onClick={props.navBarToggle}> <MenuIcon /> </IconButton> </Toolbar> </AppBar> }

paket:
"dependencies": { "@apollo/react-hooks": "^3.1.1", "@material-ui/core": "^4.4.3", "@material-ui/icons": "^4.4.3", "apollo-boost": "^0.4.4", "graphql": "^14.5.8", "next": "^9.0.7", "next-with-apollo": "^4.3.0", "react": "^16.10.1", "react-dom": "^16.10.1" }

@oliviantri

Masih kesalahan ini terjadi dengan [email protected] .

Secara internal material-ui menggunakan layoutEffect ()?

Atau gunakan "useIsomorphicLayoutEffect"?

https://github.com/mui-org/material-ui/issues/15798#issuecomment -528311534

Saya ingin SSR dengan Material UI.

Jika Anda punya waktu, silakan lihat contoh yang menunjukkan peringatan ini:

https://github.com/saltyshiomix/react-ssr/tree/master/examples/with-jsx-material-ui

Terhormat,

@saltyshiomix Tampaknya peringatan tersebut berasal dari https://github.com/saltyshiomix/react-ssr/blob/50895251cb950cfa4ccccf03bff43011b4303e51/packages/core/lib/webpack/material-ui.js#L7.

Penggunaan API sisi server di sisi klien memicu peringatan ini.
@hburrows juga melaporkan di # 17850 bahwa CSS kosong dalam kasus ini.

Jadi, saya akan merekomendasikan untuk tidak melakukan dua kali render dua kali pada klien, untuk pertimbangan kinerja. Anda akan menghindari masalah tersebut pada saat bersamaan. Apakah itu berhasil untuk Anda?

@oliviantri

Anda benar sekali, dan memecahkan masalah!

Saya salah paham tentang API, maaf.

@ eps1lon Haruskah kita membuka kembali dan menerapkan solusi berbasis canUseDOM (dari basis kode React)? Kami memiliki 7 orang berbeda yang berinteraksi dengan masalah ini dalam 3 bulan. Ini tidak banyak, sejauh ini, tampaknya masalah yang mendasari muncul di basis kode orang. Saya senang dengan cara apa pun dan saya cenderung belum melakukan apa pun.

Perhatikan bahwa ini lebih luas untuk efek tata letak, kami menjalankan typeof window !== 'undefined' di beberapa tempat lain.

Saya memiliki masalah yang persis sama. Faktanya, semua orang yang menggunakan material-ui dan next-with-apollo dengan opsi always akan mengalami masalah ini.

Menggunakan next-with-apollo dengan always options memungkinkan untuk mengambil data langsung dari komponen dan ini benar-benar nyaman (ini memungkinkan saya untuk menghindari 10 HOC berbeda untuk meneruskan data, jadi lebih sedikit overhead).

Jadi, jika Anda dapat mengimplementasikan API "canUseDom", itu akan sangat bagus !!

Selain itu, masalah telah ditutup di sini dan dibuka di paket next-with-apollo, tetapi pengelola paket ini tidak dapat melakukan apa pun karena masalah tersebut berasal dari Material UI.

@ lcswillems Saya akan merekomendasikan getDataFromTree: "never" . Saya telah menggunakan Apollo dalam produksi setahun yang lalu. getDataFromTree adalah pembunuh kinerja bagi kami, kami berbicara tentang ~ 200 ms untuk langkah ini. Pada akhirnya, kami menggunakan opsi yang setara dengan 'ssr' untuk halaman yang paling jarang (dev lebih cepat, halaman lebih lambat) dan 'never' (dev lebih lambat, halaman lebih cepat) untuk halaman yang paling sering dikunjungi.

Saya rasa proposal di https://github.com/mui-org/material-ui/issues/15798#issuecomment -528311534 tidak akan membantu kasus Anda. Ini dirancang untuk orang-orang yang memiliki masalah saat mereka merender di server dan memiliki jendela yang bocor, di suatu tempat.

Dalam kasus Anda, saya percaya bahwa itu adalah saat Anda melakukan render pada klien. Sejauh yang saya tahu, tidak ada yang bisa kami lakukan. Kami dibatasi oleh React.

Jadi, jika Anda dapat mengimplementasikan API "canUseDom", itu akan sangat bagus !!

Silakan lihat https://github.com/mui-org/material-ui/issues/15798#issuecomment -535914051 untuk mengetahui mengapa hal ini tidak mungkin dilakukan untuk perpustakaan. Atau

Masalah umumnya adalah bahwa peringatan ini bergantung pada API yang Anda gunakan, bukan lingkungan tempat Anda berada. Jadi, apa pun yang mengandalkan sniffing lingkungan tidak akan pernah lengkap karena Anda dapat menggunakan sebagian besar react-dom / server di browser atau dalam pengujian node lingkungan dengan jsdom global.

- https://github.com/facebook/react/issues/14927#issuecomment -549516297

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

revskill10 picture revskill10  ·  3Komentar

rbozan picture rbozan  ·  3Komentar

finaiized picture finaiized  ·  3Komentar

FranBran picture FranBran  ·  3Komentar

sys13 picture sys13  ·  3Komentar