React: eslint-plugin-react-hooks: Kondisi di luar kesalahan 'Hook dipanggil bersyarat'

Dibuat pada 19 Sep 2019  ·  4Komentar  ·  Sumber: facebook/react

Apakah Anda ingin meminta fitur atau melaporkan bug ?

BUG (mungkin)

Bagaimana perilaku saat ini?

Plugin menunjukkan kesalahan ini:

React Hook "useState" dipanggil secara kondisional. React Hooks harus dipanggil dalam urutan yang sama persis di setiap render komponen. Apakah Anda tidak sengaja memanggil React Hook setelah pulang lebih awal? (react-hooks / rules-of-hooks) eslint

Tapi saya tidak berpikir saya memanggil pengait apa pun secara kondisional.

Kode:

https://codesandbox.io/s/exciting-bhabha-mqj7q

function App(props) {
  const someObject = { propA: true, propB: false };

  for (const propName in someObject) {
    if (propName === true) {
      console.log("something");
    } else {
      console.log("whatever");
    }
  }

  // THE PLUGIN ERROR MSG ON THIS useState
  const [myState, setMyState] = useState(null);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

image

Apa perilaku yang diharapkan?

Plugin tidak akan menampilkan kesalahan dalam situasi ini.

Versi React mana, dan browser / OS mana yang terpengaruh oleh masalah ini?

image

ESLint Rules Bug

Komentar yang paling membantu

Semua 4 komentar

Saya perhatikan bahwa untuk contoh khusus ini:

pathsFromStartToEnd adalah 3
allPathsFromStartToEnd adalah 2

juga possiblyHasEarlyReturn adalah true


Kesalahan khusus ini dilaporkan ketika pathsFromStartToEnd dan allPathsFromStartToEnd tidak sama.

Lihat RulesOfHooks.js baris 404


Jika Anda mengabstraksi kode di dalam loop for..in menjadi fungsi terpisah, kesalahan lint akan hilang.

Dalam kasus ini, pathsFromStartToEnd dan allPathsFromStartToEnd keduanya sama dengan 2 :

  const someObject = { propA: true, propB: false };
  const someFunction = (propName) => {
    if (propName === true) {
      console.log("something");
    } else {
      console.log("whatever");
    }
  }
  for (const propName in someObject) {
    someFunction(propName)
  }
  const [myState, setMyState] = useState(null);

Saya masih tidak yakin mengapa.

@gaearon , saya membuat MR yang menangani dan memperbaiki masalah ini (# 16853).

Alasan utama ini terjadi adalah bahwa nilai allPathsFromStartToEnd dihitung dengan salah.
Dalam contoh ini, jumlah jalur dari awal hingga akhir harus 3, tetapi fungsi mengembalikan 2.

Alasan hal ini terjadi adalah karena cache jalur siklik yang cacat. Jadi dalam traverse grafik normal, kita memerlukan riwayat jalur juga, tetapi ini hanya membutuhkan daftar elemen siklik, dan elemen yang mengarah ke jalur ini tidak diketahui.
Akibatnya, ketika kondisi digunakan dalam for...in obj , berdasarkan arah kita mungkin kehilangan beberapa jalur.

Ini masih menjadi masalah dengan 2.4.0, repro yang sedikit lebih sederhana:

import * as React from "react";

function Component() {
  let isLastEven = false;
  for (let x of [1, 2, 3]) {
    if (x % 2 == 0) {
      isLastEven = true;
    } else {
      isLastEven = false;
    }
  }
  let y = React.useMemo(() => 1, []);
  return <div>{y}</div>;
}

dapatkah # 16853 dibuka kembali?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat