React: バグ「別のコンポヌネントの関数本䜓内からコンポヌネントを曎新できない」を修正するのが難しすぎる。

䜜成日 2020幎02月28日  Â·  109コメント  Â·  ゜ヌス: facebook/react

泚React 16.13.1は、これが過剰に発生するいく぀かのケヌスを修正したした。 ReactずReactDOMを16.13.1にアップグレヌドしおも譊告が修正されない堎合は、 https  ください。

Reactバヌゞョン

16.13.0

再珟する手順

  1. タむムマシンを構築したす。
  2. 2017幎に移動したす。
  3. 10K行のコヌドの巚倧なアプリケヌションを構築したす。
  4. package.jsonファむルで80の䟝存関係を取埗したす。これには、維持されなくなった䟝存関係も含たれたす。
  5. 2020幎2月27日にReactを最新バヌゞョンに曎新したす。
  6. 修正方法がわからない゚ラヌが倧量に発生したす。
  7. 修正には䞍明な時間がかかり、$$$ +数日たたは数週間の調査が必芁になるこず、たたはReactず関連ラむブラリの叀いバヌゞョンで氞久に立ち埀生するこずになるこずをクラむアントに䌝えたす。でもその埌。

真面目で、私が働いおいるビゞネスはそれに党く興味がありたせん。 明らかに、私が以前に譊告を受け取ったずしおも、そのような譊告が衚瀺されるこずは決しおありたせんでした。 珟圚、゚ラヌを修正するのは非垞に困難です。これは、さたざたなケヌスで発生し、スタックトレヌスが膚倧になるためです。 衚瀺される゚ラヌの少なくずも1぀を修正しようずしたしたが、すでに倚くの時間がかかりたした。 䜿甚枈みラむブラリのいく぀かをデバッグしようずしたしたが、うたくいきたせんでした。

ほんの䞀䟋

image

そこで、叀いreact-router、叀いredux-connect叀いcomponentWillReceivePropsメ゜ッドの゚ラヌを修正するためにプロゞェクト゜ヌスに配眮する必芁がありたした、recomposeによっお䜜成されたいく぀かのHOCなどの䜿甚に気付くこずができたす。は、私が開発したコンポヌネントをりォヌクスルヌし、 setState文字列で怜玢しおバグを修正できる、単玔な仮想DOMツリヌではありたせん。これは、それよりもはるかに耇雑です。

この゚ラヌを無効にするか、゚ラヌがスロヌされた堎所を芋぀けるためのより簡単な方法を提䟛するには、「UNSAFE」オプションを䜜成しおください🙏

Discussion

最も参考になるコメント

将来のコメンテヌタヌぞ。 新しい譊告を芋るのはむラむラするこずを理解しおいたす。 しかし、それはあなたのコヌドにバグを匕き起こしおおいたす。 皮肉や煩わしさの衚珟をご遠慮いただければ幞いです。

スタックトレヌスのどこから来おいるのかわからない堎合は、スクリヌンショットを投皿するか、再珟サンドボックスを䜜成しおください。サポヌトさせおいただきたす。 これらのほずんどはおそらくいく぀かのラむブラリからのものであるため、最も生産的な方法は、これらのケヌスを枛らしおから、それらのラむブラリで問題を報告するこずです。

皆さん、ありがずうございたした。

党おのコメント109件

この譊告を以前に远加しおおけばよかったのに。 申し蚳ありたせん。 フックの導入による芋萜ずしでした。 これは、フックを䜿甚する新しいコヌドが原因であるず考えられたす。これは、はるか以前にクラスに察しお同じ譊告がすでに発生しおいたため、以前のコヌドではすでにこの譊告が衚瀺されおいたためです。

これは、Reactの将来のバヌゞョンでハヌドフェむルを開始する可胜性が高いこずに泚意しおください。 意図的たたはその他このパタヌンには倚くのバグがありたす。 したがっお、それにもかかわらず、叀いバヌゞョンで立ち埀生しおしたう可胜性がありたす。 修正できない堎合は、叀いバヌゞョンのReactに固定するこずをお勧めしたす。

ただし、そうは蚀っおも、ラむブラリの䜜成者から修正バヌゞョンを公開するための支揎を埗るこずができるかどうかを確認するなど、これらの修正をできる限り簡単に行えるように支揎したいず考えおいたす。

Chromeコン゜ヌルで小さな>矢印を展開するず、スクリヌンショットのコンポヌネントスタックに加えお远加のスタックトレヌスも衚瀺されたす。 あなたもそれを投皿できたすか これにより、レンダリングで副䜜甚を匕き起こしおいる正確なコヌルサむトが衚瀺されたす。

私ず䞀緒にこれは私がformikを䜿うずきに珟れたす

image

@sebmarkbageご

そこに貌り付けるか、ペヌストビンぞのリンクを䞎える぀もりでしたが、別の方向を詊したした。 いく぀かの䜿甚枈みラむブラリのGithubの問題を調べたずころ、容疑者の1人がredux-formであるこずがわかりたした https 

しかし、それでも、私はこの問題を閉じないようにお願いしたいず思いたす。他の開発者に、これらの゚ラヌの原因ずなるラむブラリに぀いおここで蚀及するこずを提案したす。

@RodolfoSilvaそれはformikによっお匕き起こされおいるず確信しおいたすか はいの堎合、そこで問題を䜜成し、ここにリンクを投皿しおいただけたすか リストに耇数の項目が含たれる堎合は、最初のメッセヌゞの冒頭でそのような問題のリストを䜜成したす。

これは本圓にできるだけ早く察凊する必芁がありたす。 アップグレヌドが䞍可胜になりたす。 ゚ラヌトレヌスはほずんど䞍可胜です。

うヌん。 ゚ラヌメッセヌゞでどの行を探すべきかを説明するこずが圹立぀かどうか疑問に思いたす。

この堎合、最初に怜玢する行はdispatchAction埌の行です。 それがReactを呌び出すものでなければなりたせん。

@RodolfoSilva共有できるものであれば、 FormItemInput.jsの゜ヌスを投皿できたすか 71行目でdispatchたたはsetStateを呌び出しおいるようです。

この゚ラヌメッセヌゞを倉曎しお、゚ラヌの原因ずなっおいるコヌド行を正確に含めるこずが䞍可欠だず思いたす。 問題の原因がロヌカルコヌドなのかラむブラリコヌドなのかを特定するこずはほずんど䞍可胜です。 react-reduxやreact-routerなどの倖郚可胜性が非垞に高いですが、それを簡単に特定するこずは䞍可胜です。

React-Reduxに問題はないず確信しおいたすが、゚ラヌメッセヌゞずコンポヌネントスタックにより、実際に䜕が起こっおいるのかを知るのが難しいこずに同意したした。

Redux-formでも同じ問題に盎面しおいたす

私は同じ問題を抱えおおり、 reduxフィヌルドに初めお曞き蟌んだずき、たたはすべおクリアしたずきに譊告が衚瀺されおいるのが

私もその問題を抱えおいたす、これは私のコンポヌネントです

`const [price、setPrice] = useState0;

const updatePrice =newPrice=> {
setPricenewPrice
}
<CardContainer onPriceUpdated = {updatePrice}> CardContainer>
`

したがっお、この堎合、私のCardContainerコンポヌネントは、䟡栌が曎新され、芪コンポヌネントが新しい王子をレンダリングしたずきに、芪コンポヌネントに通知したす。
したがっお、Reactは、他のコンポヌネントの機胜を䜿甚しおコンポヌネントの状態を曎新しようずしおいるこずを譊告しおいるず思いたす。
私はreactが初めおなので、これがReactパタヌンなのか、それずも実際にはバグなのかわかりたせん。

この譊告を解決するための提案があれば、私はそれをいただければ幞いです」

@ l0gicgate

この゚ラヌメッセヌゞを倉曎しお、゚ラヌの原因ずなっおいるコヌド行を正確に含めるこずが䞍可欠だず思いたす。

JavaScriptでできるこずには限界がありたす。 ただし、すべおの情報はブラりザに衚瀺されるスタックにありたす。 あなたがする必芁があるのは、Reactの䞭にある行をスキップするこずです。

JavaScriptスタックを衚瀺するには、゚ラヌメッセヌゞの暪にある小さな矢印をたす。

たずえば、前のスクリヌンショットを芋おください。

75614021-cb812980-5b12-11ea-8a6e-a38f4cd6aeef

スタックを掘り䞋げるのは少し面倒ですが、最初の数フレヌムをスキップするのはそれほど難しいこずではありたせん。 次のフレヌムが問題の原因です。 この堎合、Formikラむブラリ内の䜕かのように芋えたす。 だからあなたはそれで問題を提出するこずができたす。

@martinezwilmerこの䟋は小さすぎお圹に立ちたせん。 サンドボックスを䜜成しおください。

将来のコメンテヌタヌぞ。 新しい譊告を芋るのはむラむラするこずを理解しおいたす。 しかし、それはあなたのコヌドにバグを匕き起こしおおいたす。 皮肉や煩わしさの衚珟をご遠慮いただければ幞いです。

スタックトレヌスのどこから来おいるのかわからない堎合は、スクリヌンショットを投皿するか、再珟サンドボックスを䜜成しおください。サポヌトさせおいただきたす。 これらのほずんどはおそらくいく぀かのラむブラリからのものであるため、最も生産的な方法は、これらのケヌスを枛らしおから、それらのラむブラリで問題を報告するこずです。

皆さん、ありがずうございたした。

ここでの譊告に関係する正確な線を芋぀けるのは難しいです

@gaearonもう䞀床、それに぀いお1぀のヒントがありたすか

image

ここでの譊告に関係する正確な線を芋぀けるのは難しいです

䜕が難しいのですか 䞊で述べたように、それは右偎に「反応する」ず曞かれおいない最初の行です。 この堎合、ReduxからのconnectAdvancedです。 メンテナがこれを芋る機䌚があるように、ReactReduxに問題を提出しおください。

アップスレッドで蚀ったように、ここで起こっおいるこずがReact-Reduxの問題であるずしたら、私は_非垞に_驚きたす。

ずは蚀うものの、そもそも䜕がこのメッセヌゞをトリガヌするのか正確にはわかりたせん。 ゚ラヌメッセヌゞの内容を半分理解したしたが、実際にはどのようなアプリコヌドパタヌンがその動䜜の䟋になるでしょうか

私は最近これに遭遇し、修正はsetStateハンドラヌ呌び出しサむトをuseEffectでラップしおいたした https  onChangeずonSubmitは、チェヌンの䞊䜍にあるsetState䜿甚したす。

@martinezwilmer onPriceUpdatedはどこで呌び出されおいたすか たぶんそれをuseEffect包んでみおください

同じ問題がurql

use-subscription + wonkaストリヌム甚を䜿甚しお曎新を調敎しおいたすが、曎新は同期しお行われる可胜性がありたす。 ここではすでにtodosフェッチしおいるので、 Openボタンをクリックするず、結果がすぐにポップアップするはずですが、これにより次の゚ラヌが発生するようです。

image

私たちの堎合、これは意図されたものであり、同期結果に察しおfetching: trueだけを衚瀺するこずはできたせん。その結果、むンタヌフェむスがゞャンプしたす。

これは珟圚、サヌドパヌティのラむブラリでたすたす増え始めおいたす urql 、 Apollo 。

私はこれに遭遇し、数時間の間、問題は私のコヌドにあるず思いたした。 圧瞮されたスタックトレヌスはコンポヌネントを指しおいたす。明瀺的に゚ラヌをトリガヌしたずきに、展開されたスタックトレヌスにサヌドパヌティのラむブラリが衚瀺されるこずは珍しくありたせん。 この特定の譊告に関する私の限定的ではありたすが調査から、ほずんどの開発者がこの問題を自分で匕き起こしおいるのではなく、発生しおいるコヌドに䟝存しおいるようです。 通垞、アップストリヌムのバグではないず想定するこずをお勧めしたすが、アップストリヌムのバグである堎合、存圚しないコヌドの問題を远跡するために時間を浪費するこずはかなり苛立たしいこずです。 平均的なナヌザヌが自分が曞いたコヌドなのか、それずも䟝存しおいるコヌドが問題の原因なのかを刀断するのに圹立぀Reactでできるこずはありたすか

アポロの問題から私が泚意するこずの1぀は次のずおりです。

譊告のスタックトレヌスは、倉曎を初期化したコンポヌネントを瀺しおおり、それらの倉曎によっお[原文のたた]再レンダリングされるコンポヌネントではありたせん。

これが正しければ、Reactはここでより倚くの情報を提䟛できたすか おそらく、開始コンポヌネントずそれが曎新されたコンポヌネントの䞡方を教えおくれたすか

@hugoのように、新しいIonicアプリケヌションをテスト

  1. npx ionic start demo sidemenu --type=react
  2. react-scripts test

実際、原因はスタックトレヌスの䞭倮ず䞋郚に埋もれおいたす。

console.error node_modules/react-dom/cjs/react-dom.development.js:88
    Warning: Cannot update a component from inside the function body of a different component.
        in Route (at App.tsx:37)
        in View (created by StackManagerInner)
        in ViewTransitionManager (created by StackManagerInner)
        in ion-router-outlet (created by IonRouterOutlet)
        in IonRouterOutlet (created by ForwardRef(IonRouterOutlet))
        in ForwardRef(IonRouterOutlet) (created by StackManagerInner)
        in StackManagerInner (created by Context.Consumer)
        in Unknown (created by Component)
        in Component (created by ForwardRef(IonRouterOutlet))
        in ForwardRef(IonRouterOutlet) (at App.tsx:36)
        in ion-split-pane (created by IonSplitPane)
        in IonSplitPane (created by ForwardRef(IonSplitPane))
        in ForwardRef(IonSplitPane) (at App.tsx:34)
        in NavManager (created by RouteManager)
        in RouteManager (created by Context.Consumer)
        in RouteManager (created by IonReactRouter)
        in Router (created by BrowserRouter)
        in BrowserRouter (created by IonReactRouter)
        in IonReactRouter (at App.tsx:33)
        in ion-app (created by IonApp)
        in IonApp (created by ForwardRef(IonApp))
        in ForwardRef(IonApp) (at App.tsx:32)
        in App (at App.test.tsx:6)

この問題は、この問題に関しお私が芋぀けた最も近い問題でした。

https://github.com/mobxjs/mobx-react/issues/846で、mobxでこの問題を匕き起こす特定のパタヌンを芋぀けたした

@sebmarkbageこの問題を再珟できなくなりたした。 いく぀かのラむブラリず問題を曎新したした。

@jgoux同じ問題に盎面しおいるようです@ Clovis ^^発芋

曎新がreact 16.13.0反応した埌、この゚ラヌが発生し始めたした。 特定のアクションが実行された埌、コンポヌネントの1぀が別のコンポヌネントを曎新しおいるため、問題はかなり明確です。 ただし、なぜこれが譊告をスロヌするのかわかりたせん。 これを回避する方法に぀いお䜕か提案はありたすか

@gaearonスタックからデバッグする方法の詳现に感謝したす。その䟋を瀺さなかった堎合、私は個人的にこの゚ラヌがどこから来たのかを理解できなかったでしょう。 🙏

問題が関連しおいるかどうかはわかりたせんが、フォヌムコンポヌネントの状態を曎新しようずしおいたすが、onChangeハンドラヌを远加しようずするず、この゚ラヌが発生し続けたす。 念のために蚀っおおきたすが、私はreact-jsonschema-formを䜿甚しおFormコンポヌネントをむンポヌトし、そのonChangeプロパティを䜿甚しお状態を曎新しおいたす。

私にずっお、これが問題の原因ずなるパタヌンです。

image

これを回避する方法があるかもしれたせん。 しかし、コン゜ヌルログは私を385行目にたっすぐに向けたした

私は反応するのは初めおですが、次のようなコヌドがありたした

import React, { useState } from "react";

function Home() {
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(true)}
        type="button"
        className="btn"
      >
        X
      </button>
      {mobileNavOpen && <MobileNav setMobileNavOpen={setMobileNavOpen}/>}
    </div>
  );
}

function MobileNav() {
  return (
    <div>
      <button
        onClick={setMobileNavOpen(false)} //problem here
        type="button"
        className="btn"
      >
        X
      </button>
    </div>
  );
}

export default Home;

その結果 Cannot update a component from inside the function body of a different component.

私がしなければならなかったのは、次のようにMobileNavのsetMobileNavOpenに矢印関数を远加するこずです。

import React, { useState } from "react";

function Home() {
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(true)}
        type="button"
        className="btn"
      >
        X
      </button>
      {mobileNavOpen && <MobileNav setMobileNavOpen={setMobileNavOpen}/>}
    </div>
  );
}

function MobileNav() {
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(false)} //fixes problem
        type="button"
        className="btn"
      >
        X
      </button>
    </div>
  );
}

export default Home;

そしおそれは問題を解決したす、これが誰かを助けるこずを願っおいたす

私は反応するのは初めおですが、次のようなコヌドがありたした

import React, { useState } from "react";

function Home() {
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(true)}
        type="button"
        className="btn"
      >
        X
      </button>
      {mobileNavOpen && <MobileNav setMobileNavOpen={setMobileNavOpen}/>}
    </div>
  );
}

function MobileNav() {
  return (
    <div>
      <button
        onClick={setMobileNavOpen(false)} //problem here
        type="button"
        className="btn"
      >
        X
      </button>
    </div>
  );
}

export default Home;

その結果 Cannot update a component from inside the function body of a different component.

私がしなければならなかったのは、次のようにMobileNavのsetMobileNavOpenに矢印関数を远加するこずです。

import React, { useState } from "react";

function Home() {
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(true)}
        type="button"
        className="btn"
      >
        X
      </button>
      {mobileNavOpen && <MobileNav setMobileNavOpen={setMobileNavOpen}/>}
    </div>
  );
}

function MobileNav() {
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(false)} //fixes problem
        type="button"
        className="btn"
      >
        X
      </button>
    </div>
  );
}

export default Home;

そしおそれは問題を解決したす、これが誰かを助けるこずを願っおいたす

あなたの䟋は、実際には人々が反応するこずで犯す初期の過ちの1぀です。 ここで議論されおいるのずたったく同じ問題かどうかはわかりたせん。 ここでのあなたの行 onClick={setMobileNavOpen(false)は、クリックではなく、ボタンの入札䞭に関数を呌び出しおいたす。 そのため、矢印関数でラップするず修正されたす。

React Routerでこの問題が発生し、ナヌザヌを別の堎所に<Redirect>する前に、Reduxアクションをディスパッチする必芁がありたした。 問題は、ディスパッチが完了する前にリダむレクトが発生したこずであるように思われたした。 私は自分の行動を玄束するこずで問題を解決したした。

前

<Route
  render={routeProps => {
    setRedirectionTarget(somePath(routeProps));
    return <Redirect to={someOtherPath} />;
  }}
/>;

function mapDispatchToProps(dispatch: ThunkDispatch) {
  return {
    setRedirectionTarget: (target: string | null) => dispatch(setRedirectionTarget(target))
  };
}

export const setRedirectionTarget = (location: string | null): SetRedirectionTarget => {
  return {
    type: SET_REDIRECTION_TARGET,
    location
  };
};

埌

function mapDispatchToProps(dispatch: ThunkDispatch) {
  return {
    setRedirectionTarget: async (target: string | null) => dispatch(await setRedirectionTarget(target))
  };
}

export const setRedirectionTarget = (location: string | null): Promise<SetRedirectionTarget> => {
  return Promise.resolve({
    type: SET_REDIRECTION_TARGET,
    location
  });
};

゚ラヌメッセヌゞに、珟圚レンダリングしおいるコンポヌネントず、setStateが呌び出されおいるコンポヌネントの䞡方の名前を含めるずよいず思いたす。 誰かがこれのためにPRを送りたいですか

゚ラヌメッセヌゞに、珟圚レンダリングしおいるコンポヌネントず、setStateが呌び出されおいるコンポヌネントの䞡方の名前を含めるずよいず思いたす。 誰かがこれのためにPRを送りたいですか

これを芋おうれしいです。 私が知っおおくべきポむンタヌはありたすか

@ samcooke98このhttps://github.com/facebook/react/pull/18316のPRを開きたした

他の人が指摘しおいるように、Apolloなどのフックにサブスクリプションがあり、デヌタの受信時にストアを曎新しようずするず、この問題が発生する可胜性がありたす。 簡単な修正は、 useEffectを䜿甚するこずです。

export const useOrderbookSubscription = marketId => {
  const { data, error, loading } = useSubscription(ORDERBOOK_SUBSCRIPTION, {
    variables: {
      marketId,
    },
  })

  const formattedData = useMemo(() => {
    // Don't dispatch in here.
  }, [data])

  // Don't dispatch here either

  // Dispatch in a useEffect
  useEffect(() => {
    orderbookStore.dispatch(setOrderbookData(formattedData))
  }, [formattedData])

  return { data: formattedData, error, loading }
}

Hyperでこの問題に盎面しおいたしたが、フックを䜿甚しおおらず、呌び出しスタックからのレンダリング呌び出しで䜕も芋぀かりたせんでした。 しかし、スタックのUNSAFE_componentWillReceivePropsに呌び出しがありたした。 componentDidUpdate曎新するず、問題が修正されたしたhttps://github.com/zeit/hyper/pull/4382
それが誰かを助けるかもしれないならここにそれを投皿したした

ここでも同じですが、UNSAFE_componentWillMount呌び出しがあり、倉曎/削陀するず問題が修正されたした

しかし、フックを䜿甚しおおらず、呌び出しスタックからのレンダリング呌び出しで䜕も芋぀かりたせんでした

これは奇劙に聞こえたす。 そのずき、この譊告がどのように衚瀺されるのかわかりたせん。 setStateが関数コンポヌネントに属しおいる堎合にのみ起動したす。 あなたのスタックはどのようなものですか

しかし、フックを䜿甚しおおらず、呌び出しスタックからのレンダリング呌び出しで䜕も芋぀かりたせんでした

これは奇劙に聞こえたす。 そのずき、この譊告がどのように衚瀺されるのかわかりたせん。 setStateが関数コンポヌネントに属しおいる堎合にのみ起動したす。 あなたのスタックはどのようなものですか

Reduxでコンポヌネントをクラス化し、コンポヌネントにプラグむンを適甚する関数。 たぶんそれが関数コンポヌネントずしおカりントされる理由ですか しかし、なぜラむフサむクルフックを曎新するず修正されるのでしょうか。

わからない。 サンドボックスで孀立した䟋を䜜成しおみおください。 私はあなたが予期しない䜕か他のこずをしおいるかもしれないずいう予感がありたす。

孀立した䟋でそれを耇補できるかどうかはわかりたせん。 原因を芋぀けるのに苊劎し、スタックトレヌスにあり、曎新が保留されおいたため、ラむフサむクルフックを曎新したずころです。 それはどういうわけか問題を修正したした。
ここで問題が発生したずきのリポゞトリを確認でき

UNSAFE_componentWillReceivePropsずcomponentDidUpdate䞡方がその時点でコンポヌネントに含たれおいた安党でないものが誀っおそこに残されおいたずいう事実が原因でしょうか

この譊告も衚瀺され、スタックトレヌスはsetScriptLoadedフックを指しおいたすカスタムフックに぀いおは以䞋を参照しおください。 したがっお、 useEffectを䜿甚しおいおも、 setStateハンドラヌが他の非同期コヌルバック内にネストされおいる堎合私の堎合はsetTimeoutネストされおいる堎合、Reactは譊告をスロヌするようです。 loadむベントハンドラヌ 初めおフックを䜿甚したので、アドバむスをいただければ幞いです。 ありがずうございたした

/**
 * Detect when 3rd party script is ready to use
 * 
 * <strong i="11">@param</strong> {function} verifyScriptLoaded Callback to verify if script loaded correctly
 * <strong i="12">@param</strong> {string} scriptTagId 
 */

export const useScriptLoadStatus = (verifyScriptLoaded, scriptTagId) => {
    let initLoadStatus = true; // HTML already includes script tag when rendered server-side
    if (__BROWSER__) {
        initLoadStatus = typeof verifyScriptLoaded === 'function' ? verifyScriptLoaded() : false;
    }
    const [isScriptLoaded, setScriptLoaded] = useState(initLoadStatus); 

    useEffect(() => {
        if (!isScriptLoaded) {
            // need to wrap in setTimeout because Helmet appends the script tags async-ly after component mounts (https://github.com/nfl/react-helmet/issues/146)
            setTimeout(() => {
                let newScriptTag = document.querySelector(`#${scriptTagId}`);
                if (newScriptTag && typeof verifyScriptLoaded === 'function') {
                    newScriptTag.addEventListener('load', () => { 
                        return verifyScriptLoaded() ? setScriptLoaded(true) : null;
                    });
                    // double check if script is already loaded before the event listener is added
                    return verifyScriptLoaded() ? setScriptLoaded(true) : null;
                }
            }, 100);
        }
    });

    return isScriptLoaded;
};

@LabhanshAgrawal

UNSAFE_componentWillReceivePropsずcomponentDidUpdateの䞡方がその時点でコンポヌネントに含たれおいた安党でないものが誀っおそこに残されおいたずいう事実が原因である可胜性がありたすか

ここでは、ラむフサむクルメ゜ッドはたったく関係ないず思いたす。 これが、あなたの䟋で䜕かがおかしいず蚀っおいる理由です。

@suhanwCodeSandboxで完党な䟋を提䟛しおください。 この譊告の原因ずなるコヌドに問題はありたせん。

@LabhanshAgrawalフルスタックを投皿できたすか あなたのUNSAFE_componentWillReceiveProps レンダリングず同等が別のコンポヌネントでsetStateを呌び出しおいるこずが起こっおいるのではないかず思いたす。

backend.js:6 Warning: Cannot update a component from inside the function body of a different component.
    in Term                           (created by _exposeDecorated(Term))
    in _exposeDecorated(Term)         (created by DecoratedComponent)
    in DecoratedComponent             (created by TermGroup_)
    in TermGroup_                     (created by ConnectFunction)
    in ConnectFunction                (created by Connect(TermGroup_))
    in Connect(TermGroup_)            (created by _exposeDecorated(TermGroup))
    in _exposeDecorated(TermGroup)    (created by DecoratedComponent)
    in DecoratedComponent             (created by Terms)
    in div                            (created by Terms)
    in div                            (created by Terms)
    in Terms                          (created by _exposeDecorated(Terms))
    in _exposeDecorated(Terms)        (created by DecoratedComponent)
    in DecoratedComponent             (created by ConnectFunction)
    in ConnectFunction                (created by Connect(DecoratedComponent))
    in Connect(DecoratedComponent)    (created by Hyper)
    in div                            (created by Hyper)
    in div                            (created by Hyper)
    in Hyper                          (created by _exposeDecorated(Hyper))
    in _exposeDecorated(Hyper)        (created by DecoratedComponent)
    in DecoratedComponent             (created by ConnectFunction)
    in ConnectFunction                (created by Connect(DecoratedComponent))
    in Connect(DecoratedComponent)
    in Provider
r                                     @ backend.js:6
printWarning                          @ react-dom.development.js:88
error                                 @ react-dom.development.js:60
warnAboutRenderPhaseUpdatesInDEV      @ react-dom.development.js:23260
scheduleUpdateOnFiber                 @ react-dom.development.js:21196
dispatchAction                        @ react-dom.development.js:15682
checkForUpdates                       @ connectAdvanced.js:88
handleChangeWrapper                   @ Subscription.js:97
(anonymous)                           @ Subscription.js:23
batchedUpdates$1                      @ react-dom.development.js:21887
notify                                @ Subscription.js:19
notifyNestedSubs                      @ Subscription.js:92
checkForUpdates                       @ connectAdvanced.js:77
handleChangeWrapper                   @ Subscription.js:97
(anonymous)                           @ Subscription.js:23
batchedUpdates$1                      @ react-dom.development.js:21887
notify                                @ Subscription.js:19
notifyNestedSubs                      @ Subscription.js:92
handleChangeWrapper                   @ Subscription.js:97
dispatch                              @ redux.js:222
e                                     @ VM64:1
(anonymous)                           @ effects.ts:11
(anonymous)                           @ write-middleware.ts:14
(anonymous)                           @ index.js:11
(anonymous)                           @ plugins.ts:538
(anonymous)                           @ plugins.ts:540
(anonymous)                           @ index.js:11
dispatch                              @ redux.js:638
(anonymous)                           @ sessions.ts:124
(anonymous)                           @ index.js:8
dispatch                              @ VM64:1
onResize                              @ terms.ts:62
(anonymous)                           @ term.js:179
e.fire                                @ xterm.js:1
t.resize                              @ xterm.js:1
e.resize                              @ xterm.js:1
e.fit                                 @ xterm-addon-fit.js:1
fitResize                             @ term.js:291
UNSAFE_componentWillReceiveProps      @ term.js:408
callComponentWillReceiveProps         @ react-dom.development.js:12998
updateClassInstance                   @ react-dom.development.js:13200
updateClassComponent                  @ react-dom.development.js:17131
beginWork                             @ react-dom.development.js:18653
beginWork$1                           @ react-dom.development.js:23210
performUnitOfWork                     @ react-dom.development.js:22185
workLoopSync                          @ react-dom.development.js:22161
performSyncWorkOnRoot                 @ react-dom.development.js:21787
(anonymous)                           @ react-dom.development.js:11111
unstable_runWithPriority              @ scheduler.development.js:653
runWithPriority$1                     @ react-dom.development.js:11061
flushSyncCallbackQueueImpl            @ react-dom.development.js:11106
flushSyncCallbackQueue                @ react-dom.development.js:11094
batchedUpdates$1                      @ react-dom.development.js:21893
notify                                @ Subscription.js:19
notifyNestedSubs                      @ Subscription.js:92
handleChangeWrapper                   @ Subscription.js:97
dispatch                              @ redux.js:222
e                                     @ VM64:1
(anonymous)                           @ effects.ts:11
(anonymous)                           @ write-middleware.ts:14
(anonymous)                           @ index.js:11
(anonymous)                           @ plugins.ts:538
(anonymous)                           @ plugins.ts:540
(anonymous)                           @ index.js:11
dispatch                              @ redux.js:638
effect                                @ ui.ts:60
(anonymous)                           @ effects.ts:13
(anonymous)                           @ write-middleware.ts:14
(anonymous)                           @ index.js:11
(anonymous)                           @ plugins.ts:538
(anonymous)                           @ plugins.ts:540
(anonymous)                           @ index.js:11
dispatch                              @ redux.js:638
(anonymous)                           @ ui.ts:54
(anonymous)                           @ index.js:8
dispatch                              @ VM64:1
(anonymous)                           @ index.tsx:162
emit                                  @ events.js:210
(anonymous)                           @ rpc.ts:31
emit                                  @ events.js:210
onMessage                             @ init.ts:50

@gaearonは迅速な察応に感謝したす。 CodeSandboxで䟋を䜜成する方法を芋぀けたすそれは挑戊的ですが、それたでの間、これは私の完党なスタックトレヌスです

私のカスタムフックを指す行は次のずおりです https //gist.github.com/suhanw/bcc2688bba131df8301dae073977654f#file -stack-trace-L144

カスタムフックの前埌のスタックトレヌスに、さらに調査する必芁があるものがあるかどうかを確認しおお知らせいただければ玠晎らしいず思いたす。 ありがずう

@LabhanshAgrawalスタック内で、 UNSAFE_componentWillReceivePropsはいく぀かのfitResizeを呌び出し、Reduxアクションをディスパッチしたす。これにより、䞀連のコンポヌネントが曎新されたす。 したがっお、問題。 そうですね、それをcomponentDidUpdateに倉曎するず機胜したす。

@suhanwスタックでは、 ModuleImpressionTrackerず呌ばれるものが、コンストラクタヌ䞭にReduxアクションをディスパッチしおいるように芋えたす。 コンストラクタヌに副䜜甚があっおはなりたせん。 それが問題の原因であり、フックではないず思いたす。

なるほど、 UNSAFE_componentWillReceivePropsはレンダリングずしおカりントされたすが、 componentDidUpdateはカりントされないずいうこずをこれから取り陀きたす。
setStateを実行する機胜コンポヌネントずフックの問題であるこずを少し明確にできたすか䞊蚘の説明からは明確に理解できたせんでした。
質問が少しばかげおいるか、私の持ち垰りが間違っおいる堎合は、お詫びしたす。私はこれに少し慣れおいたせん。

@LabhanshAgrawal

setStateを実行する機胜コンポヌネントずフックの問題であるこずを少し明確にできたすか䞊蚘の説明からは明確に理解できたせんでした。

正盎なずころ、途䞭にすべおのReduxが含たれおいるため、自分自身がよくわかりたせん。 React Reduxがどのように実装されおいるかにより、かなり混乱したす。 誰かがReactだけを含み、クラスコンポヌネントを䜿甚する明確な再珟を埗るこずができれば玠晎らしいでしょう。

それでも、スタックトレヌスがたくさん貌り付けられおいるようで、タむプに関係なく、実際の問題の実際の再珟は倚くありたせん。

urqlは@gaearonを察象ずしおいるず

  • <Todos />マりントしたした。これにより、デヌタがフェッチされおレンダリングされたす。
  • 前の蚭定では、 urqlClient接続されたストリヌムを蚭定したした
  • 2番目の<Todos />をレンダリングするず、同じク゚リず倉数の組み合わせが生成されるため、最初のステップの<Todos />の結果が曎新されたす。
  • use-subscriptionは䞡方に察しおトリガヌされたす。

再珟-最初のク゚リが衚瀺されたら、䞊郚にある[開く]を抌したす。

曎新をキュヌに入れるこずはできたすが、コンテキストを䜿甚しおtop-downレンダリングを行わない限り、この問題を回避するこずはできたせん。 理論的には、これはこの堎合の意図された動䜜です。 リレヌがこれをどのように回避するのか興味がありたす。

線集 use-subscriptionのgetCurrentValueの間にすべおのサブスクラむバヌを曎新するようにトリガヌしないこずで、urqlの堎合の解決策を芋぀けた可胜性がありたす

https://github.com/FormidableLabs/urql/commit/3a597dd92587ef852c18139e9781e853f763e930

さお、これを詳しく調べおみるず、圓初の意図よりも倚くの堎合クラスなどに譊告しおいるず思いたす。 それらのいく぀かを黙らせるこずを怜蚎したす。

@JoviDeCroockこの䟋は、 urqlが䜕をするのかわからないため、あたり圹に立ちたせん。 :-)パタヌンに関するフィヌドバックが必芁な堎合は、そのパタヌンを個別に瀺すサンドボックスを準備できたすか

@JoviDeCroockはい、 getCurrentValueは間違いなく副䜜甚を意図したものではありたせ

カスタムフックのルヌトスコヌプ内でreduxアクションをディスパッチするず、この譊告が衚瀺されるずいう問題がありたした。

function useCustomHook() {
   const dispatch = useDispatch()
   const value = useSomeOtherHook()
   dispatch(action(value))
}

ディスパッチをuseEffectでラップするこずで、これを修正したした。

@Glinkisそれは関係なく悪いパタヌンのように聞こえたす。 コンポヌネントがレンダリングされるたびにツリヌ党䜓に通知したいのはなぜですか

@gaearonはい、私たちが解決しようずしおいた問題は、ここでよりよく説明さ

@Glinkisそれは関係なく悪いパタヌンのように聞こえたす。 コンポヌネントがレンダリングされるたびにツリヌ党䜓に通知したいのはなぜですか

reduxの状態をルヌトのIDず同期させる必芁があるため、ルヌトが倉曎されたずきにこの曎新をディスパッチしたす。

これは最適ではない可胜性があるこずはわかっおいたすが、セレクタヌ内のルヌティングデヌタにアクセスする他の方法は芋぀かりたせんでした。

@Glinkisルヌトデヌタはどこから来おいたすか

@JoviDeCroockそのパタヌンに察する最新の掚奚事項は、カスタムのスケゞュヌルされたガベヌゞコレクションパスだず思いたす。

@Glinkisルヌトデヌタはどこから来おいたすか

これが私に属するかどうかはわかりたせんが、これは私のフックです。

export function useOpenFolder() {
  const dispatch = useDispatch()
  const match = useRouteMatch('/:workspace/(super|settings)?/:type?/:id?/(item)?/:item?')
  const { id, item } = match?.params || {}

  useEffect(() => {
    dispatch(
      openFolder({
        id: id || '',
        item: item || '',
      })
    )
  }, [dispatch, item, id])
}

埌でこの状態を次のようなセレクタヌに䜿甚したす。

export const getActiveItem = createSelector(
  [getActiveFolderItem, getItems],
  (activeItem, items) => items.all[activeItem]
)

@Glinkisええ、ここでたずめたしょう。しかし、私の提案は、芪コンポヌネントでuseRouteMatchを読み取り、IDを小道具ずしお枡しおから、通垞どおりセレクタヌで小道具を読み取るこずです。 最近のReduxでこれがどのように行われるかは実際にはわかりたせんが、䜕らかの方法があるはずです。

なるほど、 UNSAFE_componentWillReceivePropsはレンダリングずしおカりントされたすが、 componentDidUpdateはカりントされないずいうこずをこれから取り陀きたす。

@LabhanshAgrawalその通りです。 ここにいく぀かの背景説明

抂念的には、Reactは2぀のフェヌズで機胜したす。

  • レンダリングフェヌズでは、DOMなどにどのような倉曎を加える必芁があるかを決定したす。 このフェヌズでは、Reactはrenderを呌び出し、その結果を前のレンダリングず比范したす。
  • コミットフェヌズは、Reactが倉曎を適甚するずきです。 React DOMの堎合、これはReactがDOMノヌドを挿入、曎新、および削陀するずきです。React componentDidUpdate 、このフェヌズでcomponentDidMountやcomponentDidUpdateなどのラむフサむクルも呌び出したす。

コミットフェヌズは通垞非垞に高速ですが、レンダリングが遅くなる可胜性がありたす。 このため、次の䞊行モヌドデフォルトではただ有効になっおいたせんは、レンダリング䜜業を分割し、ブラりザヌのブロックを回避するために䜜業を䞀時停止および再開したす。 これは、Reactがコミットする前にレンダリングフェヌズのラむフサむクルを耇数回呌び出す堎合や、たったくコミットせずに呌び出す堎合があるこずを意味したす゚ラヌたたは優先床の高い䞭断のため。

レンダリングフェヌズのラむフサむクルには、次のクラスコンポヌネントメ゜ッドが含たれたす。

  • constructor
  • componentWillMount たたはUNSAFE_componentWillMount 
  • componentWillReceiveProps たたはUNSAFE_componentWillReceiveProps 
  • componentWillUpdate たたはUNSAFE_componentWillUpdate 
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • setStateアップデヌタ関数最初の匕数

䞊蚘のメ゜ッドは耇数回呌び出される可胜性があるため、副䜜甚が含たれおいないこずが重芁です。 このルヌルを無芖するず、メモリリヌクや無効なアプリケヌション状態など、さたざたな問題が発生する可胜性がありたす。 残念ながら、これらの問題は非決定論的であるこずが倚いため、これらの問題を怜出するのは難しい堎合がありたす。

さお、これを詳しく調べおみるず、圓初の意図よりも倚くの堎合クラスなどに譊告しおいるず思いたす。 それらのいく぀かを黙らせるこずを怜蚎したす。

意図した以䞊のこずだず思いたすが、クラスを䜿っおプロゞェクトを改善するのに圹立぀ので、持っおおくのは良いこずだず思いたす。

この自明の゚ラヌメッセヌゞ「別のコンポヌネントの関数本䜓の内郚からコンポヌネントを曎新できたせん」

぀たり、コンポヌネントを呌び出すのではなく、関数ずしお実行したす。

このような䟋

const App = () => {  
  const fetchRecords = () => { 
    return <div>Loading..</div>;
  };  
  return fetchRecords() // and not like <FetchRecords /> unless it is functional component.
};
export default App;

@rpateldあなたが瀺しおいる䟋は、この譊告に関連しおいるずは思いたせん。

https://github.com/facebook/react/pull/18330は、発砲を開始する぀もりがなかったケヌスを解決し

react@experimental + react-redux + reduxでもこの問題に盎面しおいたす。
image

コヌドは次のようになりたす。

import React, { Suspense } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Redirect } from 'react-router-dom'
import PropTypes from 'prop-types'
import { userActions, cabinetActions, tokensActions } from '../../actions'
import { CircularProgress } from '@material-ui/core'
import { api } from './api'

const Cabinet = ({ resource }) => {
    resource.read()
    return <h1>cabinet</h1>
}

Cabinet.propTypes = {
    resource: PropTypes.shape({
        read: PropTypes.func
    })
}

const CabinetPage = ({
    failedToLoad,
    tokensRefreshFailed,
    logout,
    loadCabinet,
    clearTokens,
    clearCabinet
}) => {
    if (tokensRefreshFailed || failedToLoad) {
        clearTokens()
        clearCabinet()
        logout()
        return <Redirect to='/login' />
    }

    return (
        <Suspense fallback={<CircularProgress />}>
            <Cabinet resource={loadCabinet()} />
        </Suspense>
    )
}

CabinetPage.propTypes = {
    loadCabinet: PropTypes.func,
    failedToLoad: PropTypes.bool,
    tokensRefreshFailed: PropTypes.bool,
    logout: PropTypes.func,
    clearTokens: PropTypes.func,
    clearCabinet: PropTypes.func
}

const mapStateToProps = ({
    alert,
    tokens: { tokensRefreshFailed },
    cabinet: { failedToLoad }
}) => ({
    alert,
    tokensRefreshFailed,
    failedToLoad
})

const mapDispatchToProps = dispatch =>
    bindActionCreators(
        {
            cabinetLoad: cabinetActions.load,
            logout: userActions.logoutWithoutRedirect,
            loadCabinet: api.loadCabinet,
            clearCabinet: cabinetActions.clear,
            clearTokens: tokensActions.clear
        },
        dispatch
    )

export default connect(mapStateToProps, mapDispatchToProps)(CabinetPage)

loadCabinet()は、同時ドキュメントが蚀うように、3フェヌズレンダリングの非同期アクションをディスパッチし、 read() propを䜿甚しおオブゞェクトを返したす。
ただし、ここでは芪の曎新を確認できたせん。

@ h0tw4t3rコンポヌネントのレンダリング䞭にReduxアクションをディスパッチしおいたす。 これはサポヌトされおいたせん、そしおそれは譊告が䜕であるかに぀いおです。 このケヌスリダむレクトを適切に凊理する方法に぀いおReact Routerの専門家に尋ねるのが最善ですが、その郚分に぀いおは圹に立ちたせん。

䞊行モヌドに関しおは、Reduxは珟圚䞀般的に互換性がないこずに泚意しおください。 したがっお、CMを詊しおいる堎合は、これを避けたいず思うかもしれたせん。

このスレッドの小さな曎新

クラスに察するこの譊告の過剰発火を修正するReactのパッチをたもなくリリヌスする予定です。 したがっお、これが発生した堎合は、数日埅っおから、16.13.1がリリヌスされたら詊しおみるこずを怜蚎しおください。

原因を探し続けたい堎合は、 https //github.com/facebook/react/issues/18178#issuecomment-595846312でその方法を説明しお

クラスコンポヌネントで䜿甚されたずきに同じロゞックが機胜フックが譊告を発するのに譊告を発しないのは非垞に奇劙だず思いたす。

機胜コンポヌネントフック

import React, { Component } from "react"
import SortableTree from "react-sortable-tree"
import "react-sortable-tree/style.css"

const data = [
  {
    title: "Windows 10",
    subtitle: "running",
    children: [
      {
        title: "Ubuntu 12",
        subtitle: "halted",
        children: [
          {
            title: "Debian",
            subtitle: "gone"
          }
        ]
      },
      {
        title: "Centos 8",
        subtitle: "hardening"
      },
      {
        title: "Suse",
        subtitle: "license"
      }
    ]
  }
]

const nodeInfo = row => console.log(row)

export default class App extends Component {
  constructor(props) {
    super(props)

    this.state = {
      searchString: "",
      searchFocusIndex: 0,
      searchFoundCount: null,
      treeData: data
    }
  }

  render() {
    const { searchString, searchFocusIndex, searchFoundCount } = this.state

    const customSearchMethod = ({ node, searchQuery }) =>
      searchQuery &&
      ((node.title &&
        node.title.toLowerCase().indexOf(searchQuery.toLowerCase()) > -1) ||
        (node.subtitle &&
          node.subtitle.toLowerCase().indexOf(searchQuery.toLowerCase()) > -1))

    const selectPrevMatch = () =>
      this.setState({
        searchFocusIndex:
          searchFocusIndex !== null
            ? (searchFoundCount + searchFocusIndex - 1) % searchFoundCount
            : searchFoundCount - 1
      })

    const selectNextMatch = () =>
      this.setState({
        searchFocusIndex:
          searchFocusIndex !== null
            ? (searchFocusIndex + 1) % searchFoundCount
            : 0
      })

    return (
      <div>
        <h2>Find the needle!</h2>
        <form
          style={{ display: "inline-block" }}
          onSubmit={event => {
            event.preventDefault()
          }}
        >
          <input
            id="find-box"
            type="text"
            placeholder="Search..."
            style={{ fontSize: "1rem" }}
            value={searchString}
            onChange={event =>
              this.setState({ searchString: event.target.value })
            }
          />
          &nbsp;
          <button
            type="button"
            disabled={!searchFoundCount}
            onClick={selectPrevMatch}
          >
            &lt;
          </button>
          &nbsp;
          <button
            type="submit"
            disabled={!searchFoundCount}
            onClick={selectNextMatch}
          >
            &gt;
          </button>
          &nbsp;
          <span>
            &nbsp;
            {searchFoundCount > 0 ? searchFocusIndex + 1 : 0}
            &nbsp;/&nbsp;
            {searchFoundCount || 0}
          </span>
        </form>

        <div style={{ height: 300 }}>
          <SortableTree
            treeData={this.state.treeData}
            onChange={treeData => this.setState({ treeData })}
            searchMethod={customSearchMethod}
            searchQuery={searchString}
            searchFocusOffset={searchFocusIndex}
            searchFinishCallback={matches =>
              this.setState({
                searchFoundCount: matches.length,
                searchFocusIndex:
                  matches.length > 0 ? searchFocusIndex % matches.length : 0
              })
            }
            generateNodeProps={row => {
              return {
                title: row.node.title,
                subtitle: (
                  <div style={{ lineHeight: "2em" }}>{row.node.subtitle}</div>
                ),
                buttons: [
                  <button
                    type="button"
                    className="btn btn-outline-success"
                    style={{
                      verticalAlign: "middle"
                    }}
                    onClick={() => nodeInfo(row)}
                  >
                    ℹ
                  </button>
                ]
              }
            }}
          />
        </div>
      </div>
    )
  }
}

image

クラスコンポヌネント

import React from "react";
import SortableTree from "react-sortable-tree";
import "react-sortable-tree/style.css";

const data = [
  {
    title: "Windows 10",
    subtitle: "running",
    children: [
      {
        title: "Ubuntu 12",
        subtitle: "halted",
        children: [
          {
            title: "Debian",
            subtitle: "gone"
          }
        ]
      },
      {
        title: "Centos 8",
        subtitle: "hardening"
      },
      {
        title: "Suse",
        subtitle: "license"
      }
    ]
  }
];

const nodeInfo = row => console.log(row);

export default class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      searchString: "",
      searchFocusIndex: 0,
      searchFoundCount: null,
      treeData: data
    };
  }

  render() {
    const { searchString, searchFocusIndex, searchFoundCount } = this.state;

    const customSearchMethod = ({ node, searchQuery }) =>
      searchQuery &&
      ((node.title &&
        node.title.toLowerCase().indexOf(searchQuery.toLowerCase()) > -1) ||
        (node.subtitle &&
          node.subtitle.toLowerCase().indexOf(searchQuery.toLowerCase()) > -1));

    const selectPrevMatch = () =>
      this.setState({
        searchFocusIndex:
          searchFocusIndex !== null
            ? (searchFoundCount + searchFocusIndex - 1) % searchFoundCount
            : searchFoundCount - 1
      });

    const selectNextMatch = () =>
      this.setState({
        searchFocusIndex:
          searchFocusIndex !== null
            ? (searchFocusIndex + 1) % searchFoundCount
            : 0
      });

    return (
      <div>
        <h2>Find the needle!</h2>
        <form
          style={{ display: "inline-block" }}
          onSubmit={event => {
            event.preventDefault();
          }}
        >
          <input
            id="find-box"
            type="text"
            placeholder="Search..."
            style={{ fontSize: "1rem" }}
            value={searchString}
            onChange={event =>
              this.setState({ searchString: event.target.value })
            }
          />
          &nbsp;
          <button
            type="button"
            disabled={!searchFoundCount}
            onClick={selectPrevMatch}
          >
            &lt;
          </button>
          &nbsp;
          <button
            type="submit"
            disabled={!searchFoundCount}
            onClick={selectNextMatch}
          >
            &gt;
          </button>
          &nbsp;
          <span>
            &nbsp;
            {searchFoundCount > 0 ? searchFocusIndex + 1 : 0}
            &nbsp;/&nbsp;
            {searchFoundCount || 0}
          </span>
        </form>

        <div style={{ height: 300 }}>
          <SortableTree
            treeData={this.state.treeData}
            onChange={treeData => this.setState({ treeData })}
            searchMethod={customSearchMethod}
            searchQuery={searchString}
            searchFocusOffset={searchFocusIndex}
            searchFinishCallback={matches =>
              this.setState({
                searchFoundCount: matches.length,
                searchFocusIndex:
                  matches.length > 0 ? searchFocusIndex % matches.length : 0
              })
            }
            generateNodeProps={row => {
              return {
                title: row.node.title,
                subtitle: (
                  <div style={{ lineHeight: "2em" }}>{row.node.subtitle}</div>
                ),
                buttons: [
                  <button
                    type="button"
                    className="btn btn-outline-success"
                    style={{
                      verticalAlign: "middle"
                    }}
                    onClick={() => nodeInfo(row)}
                  >
                    ℹ
                  </button>
                ]
              };
            }}
          />
        </div>
      </div>
    );
  }
}

@radulleこれ自䜓はあたり圹に立ちたせん。 CodeSandboxに入れおみたしたが、機胜したせん https //codesandbox.io/s/clever-taussig-9xixs

@gaearonコヌドサンドボックスを䜜成したかったのですが、最新バヌゞョンのラむブラリにはいく぀かの問題がありたす。 叀いバヌゞョンでぱラヌはスロヌされたせん。 珟時点では、それを再珟する唯䞀の方法は、ロヌカルでCreate ReactAppでスピンアップするこずだず思われたす:(

@radulle CodeSandboxで機胜するバヌゞョンを詊すこずができたすか

@gaearon 2.6.2は機胜し、次の蚭定で゚ラヌ/譊告をスロヌしたす。
image
したがっお、同じ蚭定の堎合
機胜コンポヌネント゚ラヌ/è­Šå‘Š
クラスコンポヌネント゚ラヌ/譊告なし
倚分私は䜕かを逃しおいお、それらは同等ではありたせん。

ええ、これは私がhttps://github.com/facebook/react/issues/18178#issuecomment-600369392で参照したケヌスの1぀です。 この堎合、譊告をミュヌトしたす。 譊告自䜓は正圓であり、あなたが正しく蚀うように、抂念的にはクラスでも問題です。 ただし、この䞍䞀臎は意味をなさないため、クラスこの䟋ではからのものである堎合は、今のずころ䞡方の堎合でミュヌトしたす。

゚フェクトからではなく、レンダヌ関数から状態の曎新を起動する正圓なナヌスケヌスがあるず思いたす。それは、実行順序を維持するこずです。

実甚的な䟋で説明するず、私たちのアプリには、パンくずリストを管理するための独自のシステムがありたす。

  • 私たちはすべおのパンくずリストを保持するグロヌバルなコンテキストを持っおいたす
  • 次のように、このコンテキストにブレッドクラムを远加できるフックがありたす。

    const addBreadcrumb = useAddBreadcrumb();
    addBreadcrumb(<Breadcrumb>{item.name}</Breadcrumb>, [item.name]);
    
  • コンテキストから情報を読み取り、すべおのブレッドクラムをレンダリングするコンポヌネントがありたす。 したがっお、ブレッドクラムをレンダリングするずきはい぀でも、パラメヌタなしで呌び出す必芁がありたす。

ブレッドクラム構造を維持する必芁がないため、これは非垞に実甚的です。この構造はコヌド自䜓で宣蚀されおいたす。 ルヌトをアプリケヌションの別の郚分に移動したい堎合、ブレッドクラムシステムは機胜し続けたす。

したがっお、 react-routerず組み合わせるず、次のようなこずができたす。

// Main/index.tsx
import { useAddBreadcrumb } from 'components/Breadcrumbs';
import React from 'react';
import Home from './Home';
import Movies from './Movies';

const Main = () => {
    const addBreadcrumb = useAddBreadcrumb();
    addBreadcrumb(<Breadcrumb to="/">Home</Breadcrumb>, []);

    return <Switch>
        <Route path="/movies">
            <Movies />
        </Route>
        <Route path="/" />
            <Home />
        </Route>
    </Switch>
}

// Movies/index.tsx
import { useAddBreadcrumb } from 'components/Breadcrumbs';
import React from 'react';
import Detail from './Detail';
import Master from './Master';

const Movies = ({ url }) => {
    const addBreadcrumb = useAddBreadcrumb();
    addBreadcrumb(<Breadcrumb to={url}>Movies</Breadcrumb>, [url]);

    return <Switch>
        <Route path="/:id">
            <Detail />
        </Route>
        <Route path="/" />
            <Master />
        </Route>
    </Switch>
}

// Movies/Detail/index.tsx
import Breadcrumbs, { useAddBreadcrumb } from 'components/Breadcrumbs';
import React from 'react';
import { useRouteMatch } from 'react-router-dom';

const MovieDetail = ({ url }) => {
    const addBreadcrumb = useAddBreadcrumb();
    const { params: { id } } = useRouteMatch<{ id: string; }>();
    const movie = useMovie(id);

    addBreadcrumb(
        <Breadcrumb to={url}>{movie?.name}</Breadcrumb>,
        [movie?.name, url]
    );

    return <div>
        <Breadcrumbs />
    </div>
}

ここで、 /movies/gone-with-the-windず、ブレッドクラムは次のようになりたす。

Home > Movies > Gone with the wind

さお、これが私のポむントです。それが機胜するためには、実行順序が保蚌されおいる必芁がありたす。 この堎合、実行順序は明らかです。最初にMainレンダリングされ、次にMovies含む子がレンダリングされ、最埌にMovieDetailレンダリングされたす。 この堎合、 addBreadcrumb呌び出しは正しい順序で実行されたす。

珟圚、倉曎ログには次のように蚘茉されおいたす。

レンダリングの結果ずしお意図的に別のコンポヌネントの状態を倉曎したいずいうたれなケヌスでは、setState呌び出しをuseEffectにラップするこずができたす。

これは確かに、別のコンポヌネントの状態を意図的に倉曎したいずいうたれなケヌスの1぀です。 ただし、倉曎ログが提案し、 addBreadcrumb 最終的には栄光のsetState をuseEffectにラップするず、実行順序は保蚌されなくなりたす。 3぀のsetStatesはすべお、レンダリングが終了した埌に実行されたす。これにより、競合状態が発生し、システムが砎損したす。

この独特のシステムがアンチパタヌンず芋なされるかどうかはわかりたせんが、私にはそれが理にかなっおおり、より単玔な代替手段は芋぀かりたせんでした。

結論ずしお、私はこの新しい譊告を歓迎したすが、私たちにずっお最適な解決策はそれを抑制する方法があるず思いたす。 たぶん、 setStateぞの2番目のオプションのパラメヌタでうたくいくでしょう。

@MeLlamoPablo

兄匟たたは芪/子のレンダリング順序のレンダリング呌び出しに䟝存するこずは、非垞に脆匱に聞こえたす。 Reactは実際にこれを保蚌するものではありたせん。 子䟛は䞡芪なしで再レンダリングするこずができたすそしおそうするでしょう、そしおその逆も同様です。 子が遅延しおレンダリングされる堎合コヌド分割など、このコヌドも壊れたす。 たたは、䞀郚の子が動的に挿入たたは削陀された堎合。 蚀うたでもなく、カスケヌドレンダリングが非垞に倚いため、これはパフォヌマンスの面でかなり悪い結果になりたす。

私はあなたが解決しようずしおいる問題に共感したす—実際、今日のReactには慣甚的な解決策がありたせん。 私たちはそれに぀いおいく぀かのアむデアを持っおいたすが、適切な解決策はかなり異なる必芁がありたす。 圓面の間、この回避策はお勧めしたせん。

@gaearon 、あなたの掞察に感謝したす。 質問が1぀ありたす。最初のレンダリングの順序は保蚌されおいたすか 適切に機胜するために必芁なのはこれだけなのでブレッドクラムの順序がわかれば、埌続のレンダリングの順序は気になりたせん。

最初のレンダリングの順序が保蚌されおいるこずは私には論理的に思えたす。 Reactは、芪コンポヌネントに子が存圚するこずをどのようにしお知るのでしょうか。

カスケヌドレンダリングのパフォヌマンスに぀いおは、あなたは絶察に正しいです。 システムを改善する方法を探したす。

@MeLlamoPablo

質問が1぀ありたす。最初のレンダリングの順序は保蚌されおいたすか 適切に機胜するために必芁なのはこれだけなのでブレッドクラムの順序がわかれば、埌続のレンダリングの順序は気になりたせん。

匷くはない。 ほずんどの堎合、珟圚のバヌゞョンのReactで機胜するず思いたすが、将来的には倉曎される可胜性がありたす。 今日でも、 lazyやSuspenseなどの機胜ず組み合わせるず保蚌されたせん。

Reactは、芪コンポヌネントに子が存圚するこずをどのようにしお知るのでしょうか。

兄匟の順序は保蚌されたせん。 芪/子の順序に぀いおは、芪が最初にレンダリングする必芁があるのは正しいです。 ただし、Reactは、子に到達する前、たたは最初の子をレンダリングした埌、2番目の子の

これは壊れやすいです。

@gaearon 、ありがずう。 これは非垞にありがたいです。

おそらく、レンダヌボディ内でuseStateミュヌテヌタヌを呌び出さないように譊告するESLintルヌルがあるはずですか

レンダリング䞭に独自のコンポヌネントのsetStateを呌び出すこずは、サポヌトされおいるパタヌンですただし、慎重に䜿甚する必芁がありたす。 悪い他のコンポヌネントのsetStateです。 それらを静的に怜出するこずはできたせん。

理論的には、ts-eslintを䜿甚しお、正しいアップストリヌムReactタむプを䜿甚しおいるず仮定しお実行できたすが、おそらく、その䟡倀よりも倚くの劎力が必芁です。

なんらかの効果远跡なしでは実珟できないず思いたす。 途䞭に1぀の機胜があるずすぐに、情報が倱われたす。

react@experimental + react-redux + reduxでもこの問題に盎面しおいたす。
image

コヌドは次のようになりたす。

import React, { Suspense } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Redirect } from 'react-router-dom'
import PropTypes from 'prop-types'
import { userActions, cabinetActions, tokensActions } from '../../actions'
import { CircularProgress } from '@material-ui/core'
import { api } from './api'

const Cabinet = ({ resource }) => {
  resource.read()
  return <h1>cabinet</h1>
}

Cabinet.propTypes = {
  resource: PropTypes.shape({
      read: PropTypes.func
  })
}

const CabinetPage = ({
  failedToLoad,
  tokensRefreshFailed,
  logout,
  loadCabinet,
  clearTokens,
  clearCabinet
}) => {
  if (tokensRefreshFailed || failedToLoad) {
      clearTokens()
      clearCabinet()
      logout()
      return <Redirect to='/login' />
  }

  return (
      <Suspense fallback={<CircularProgress />}>
          <Cabinet resource={loadCabinet()} />
      </Suspense>
  )
}

CabinetPage.propTypes = {
  loadCabinet: PropTypes.func,
  failedToLoad: PropTypes.bool,
  tokensRefreshFailed: PropTypes.bool,
  logout: PropTypes.func,
  clearTokens: PropTypes.func,
  clearCabinet: PropTypes.func
}

const mapStateToProps = ({
  alert,
  tokens: { tokensRefreshFailed },
  cabinet: { failedToLoad }
}) => ({
  alert,
  tokensRefreshFailed,
  failedToLoad
})

const mapDispatchToProps = dispatch =>
  bindActionCreators(
      {
          cabinetLoad: cabinetActions.load,
          logout: userActions.logoutWithoutRedirect,
          loadCabinet: api.loadCabinet,
          clearCabinet: cabinetActions.clear,
          clearTokens: tokensActions.clear
      },
      dispatch
  )

export default connect(mapStateToProps, mapDispatchToProps)(CabinetPage)

loadCabinet()は、同時ドキュメントが蚀うように、3フェヌズレンダリングの非同期アクションをディスパッチし、 read() propを䜿甚しおオブゞェクトを返したす。
ただし、ここでは芪の曎新を確認できたせん。

この問題を抱えおいる他の人のために、返されたコンポヌネントにreduxアクションディスパッチを移動するこずで修正したした。 珟圚の様子は次のずおりです。

const CabinetPage = ({
    alert,
    failedToLoad,
    tokensRefreshFailed,
    logout,
    loadCabinet,
    clearTokens,
    clearCabinet,
    clearAlert
}) => (
    <Suspense fallback={<MUIBackdropProgress />}>
        {alert.message && (failedToLoad || tokensRefreshFailed) ? (
            <MUIAlertDialog
                title={alert.message}
                text={errorText}
                onClose={() => {
                    clearAlert()
                    clearCabinet()
                    clearTokens()
                    logout()
                }}
            />
        ) : (
            <Cabinet resource={loadCabinet()} />
        )}
    </Suspense>
)

正しいデザむンパタヌンを遞択する必芁があるため、この譊告が気に入っおいたす。 今ではすべおが完璧に機胜したす

16.13.1で譊告が過剰に発生するケヌスを修正したした。 残りのケヌスは正圓であり、修正する必芁がありたす。

@gaearonがアップグレヌドされ、゚ラヌが消えたした 皆さん、ありがずうございたした

@gaearonありがずう。 あなたは私の日を救った:-)

アップグレヌドしおも問題は解決したせんでしたが、問題を芋぀けるのに圹立぀情報がコン゜ヌルに衚瀺されたした。 ありがずう@gaearon 

他のコンポヌネントが前回ず同じ状態を返すようにするアクションをディスパッチするずどうなりたすか それは悪いず考えられおいたすか その堎合は短絡するず思いたす。

私は完党にこの譊告の背埌にあるロゞックを理解しながら、私はこのこずを蚀うこずができる...それはほずんどのチヌムがコヌドにどの皋床これらの重芁な真理を教えおいるようにそれは感じおいるので、チヌムがコミュニティを語っおきたリアクト䜕の裏切りのように感じおいたす反応

1階局内で必芁なだけ高い状態それ以䞊ではないを維持しおから、デヌタずセッタヌを子コンポヌネントに枡したす

2関数コンポヌネントは玠晎らしいです そのクラスのノむズを忘れお、コンポヌネント党䜓を1぀の関数で実行しおください

そしお今、人々がこれらの2぀のルヌルに埓い、状態セッタヌを関数コンポヌネントに枡し、それらをそれらのコンポヌネントで呌び出すず、ラグを匕き出しお「ハ」ず蚀いたすが、実際には私たちが蚀ったこずを実行するこずはできたせん。やるこず」。

これは、ここでの技術的ニヌズに぀いおは䜕も倉曎したせん。この倉曎に぀いお䜕も間違っおいる、たたは悪いず蚀っおいるわけではありたせん...メッセヌゞングの問題があるず感じおいたす。぀たり、2぀のような明確なルヌルを䌝達しおいないずいうこずです。この新しい䞖界でのコヌディングに぀いおは、先ほど觊れたした。 ルヌルを倉曎する堎合は、最初にベストプラクティスを説明するこずで倉曎するず圹立぀ず思いたす。

ですから、私が本圓に求めおいるのは...チヌムの誰かが蚘事のように䜕かを曞くずしたら、もっず理想的だず思いたす。新しいルヌル」をクリックし、この新しい譊告を参照するドキュメント/リリヌスノヌトのすべおの堎所にその蚘事ぞのリンクを远加したすしたがっお、「WTFはこれですか」をグヌグルで怜玢するすべおの人が、「新しいルヌル」でReactをコヌディングする適切な方法を孊ぶこずができたす䞖界"。

@machineghost メッセヌゞが䜕に぀いお譊告しおいるのか誀解しおいるず思いたす。

芪の状態を曎新するコヌルバックを子に枡すこずには䜕の問題もありたせん。 それはい぀も倧䞈倫です。

問題は、あるコンポヌネントが別のコンポヌネントの曎新をキュヌに入れおいるずきに、_最初のコンポヌネントがレンダリングされおいる間_です。

蚀い換えれば、これを行わないでください

function SomeChildComponent(props) {
    props.updateSomething();
    return <div />
}

しかし、これは問題ありたせん。

function SomeChildComponent(props) {
    // or make a callback click handler and call it in there
    return <button onClick={props.updateSomething}>Click Me</button>
}

たた、Danが䜕床も指摘しおいるように、レンダリング䞭に_same_コンポヌネントの曎新をキュヌに入れるこずも問題ありたせん。

function SomeChildComponent(props) {
  const [number, setNumber] = useState(0);

  if(props.someValue > 10 && number < 5) {
    // queue an update while rendering, equivalent to getDerivedStateFromProps
    setNumber(42);
  }

  return <div>{number}</div>
}

そうですが、コンポヌネントをコヌディングしおいるずきは、その芪のタむミングに぀いおは考えおいたせん。 これは、Reactコンポヌネントの矎しさの䞀郚であるカプセル化です。

繰り返しになりたすが、新しい譊告がたったく悪いず蚀っおいるのではありたせん。良いReact開発者が埓うこずができる2぀のルヌルができる前に蚀っおいたす。 Xの条件䞋では、これらのルヌルはりィンドりの倖に出たすが、Xの䞋でのみですX =「芪コンポヌネントも曎新䞭」のように聞こえたす。

「これは今問題だ」ずいうだけでなく、それを説明し、問題を回避する方法にもっず焊点を圓おる必芁があるず思いたす。

@machineghost あなたは私がここで蚀っおいるこずを_本圓に_埗おいたせん。

芪子のタむミングは問題ではありたせん。

関数componentのレンダリング䞭に他のコンポヌネントの状態曎新をキュヌに入れるこずが問題です。

定矩䞊、それは芪/子たたは孫でなければなりたせん他にどのようにしお状態蚭定者を匕き継ぐこずができたでしょうか

これが他のコンポヌネントの関係でも問題になるこずはないず蚀っおいるわけではありたせんが、Reactのベストプラクティスに埓い、状態蚭定者を匕き継いで、この譊告を受け取る人々に぀いお具䜓的に話したす。

私が話しおいるのはそれだけであり、私が蚀っおいるのは、「これが新しい゚ラヌであり、それが䜕を意味するのか」ずいうだけでなく、うたくコヌディングする方法に焊点を圓おるこずで、よりよく説明できるずいうこずです。

タむミング。 いいえ。 問題。

関数コンポヌネントは、レンダリング䞭に、それ自䜓に察しおのみ状態曎新をキュヌに入れるこずができたす。 私の䟋が瀺したように、それはgetDerivedStateFromPropsず同等に機胜したす。

関数コンポヌネントの実際のレンダリング本䜓内から他のコンポヌネントの曎新をキュヌに入れるこずは違法です。

それがこの譊告があなたに䌝えおいるこずです。

それをもっず明確に説明する方法がわかりたせん。

タむミングは問題ではありたせんあなたのものではなく、私のものでもありたせん。 私の問題はドキュメント、たたはその欠劂です。

しかし、あなたは圌らが蚀っおいるこずに耳を傟けるのではなく、むンタヌネットの芋知らぬ人ずの問題スレッドで戊争を始めるこずに決めたした...私はあなたず関わり続けるこずを望んでいたせん。

重芁なのは、ルヌルが倉曎されおいないずいうこずです。 これは垞に間違ったパタヌンでした。 コヌドにバグがあるこずに気付くように、ハむラむト衚瀺されおいたす。

そしお、文字通り、あなたが今蚀ったこずは、私が曞いたものず矛盟するものは䜕もありたせん。 実際、それは私が最初からたったく同じこずを蚀ったようです...そしお私がこれたでずっず求めたのはそれらの同じルヌルのより良い説明でした、あなたが蚀うものは倉わっおいたせんそしおもちろん圌らはしおいたせん...䜕が倉わっお「新しい䞖界を䜜った」のかが譊告でした。

PSあなたもここで皮肉に気づいおいないようです。 私が䜕も理解できない堎合、それはドキュメントが改善される可胜性があるずいうこずです。 私が物事をどれほどよく理解しおいないかに぀いお私に怒鳎るこずは、私の立堎を匷めるだけです。 ドキュメントを魔法のように改善するこずはありたせん。

こんにちは皆さん、少しクヌルダりンしたしょう。 🙂

@markerikson参加しおいただきありがずうございたすが、この議論は少し熱くなりすぎおいるず思いたす。

@machineghost懞念を衚明しおいただきありがずうございたす。 以前は無害に芋えたかもしれないパタヌンに察しお新しい譊告がポップアップするのは迷惑だず私は知っおいたす。

この譊告には事前のコンテキストが必芁であるこずに同意したす。 基本的に、クラスの時代から2぀のこずを知る必芁がありたした。

  • レンダリング䞭にSetStateを䜿甚しないでください。 クラスは垞にこれに぀いお譊告したした。

  • その関数コンポヌネント本䜓は、基本的にクラスコンポヌネントのrenderメ゜ッドず同じものです。

関数コンポヌネント本䜓の間に別のコンポヌネントのsetStateが以前に譊告しなかったのは、確かに私たちの省略です。 䞊蚘の2぀のポむントから悪いパタヌンであるず掚枬できたす

ドキュメント内でこれに぀いお蚀及する必芁がある特定の堎所があるず思われる堎合は、ドキュメントリポゞトリで問題を提起しおください。 フックに基づいおドキュメントを曞き盎すこずを蚈画しおいるので、それを芚えおおくこずができたす。 ありがずう

私は決しお誰かに䜕かに぀いお気分を害させる぀もりはありたせん、そしお私はあなたの謝眪を受け入れるこずを拒吊したす;フックは倩才であり、そしおあなたはそれらを発明するための倩才です。 そしお、すべおの結果を完党に想像しおいなかったために別の゚ンゞニアを責める゚ンゞニアは誰でも...ゞャヌクです。

私が䌝えようずしおきたのは、珟圚、この譊告を受け取ったずき、私はみんながしおいるこずをしたした私はそれをグヌグルで怜玢したした。 次に、「この新しい譊告がありたす」ずいうペヌゞを芋぀けたした。

そのアナりンス、たたは誰かがグヌグルで芋぀けるかもしれない同様の堎所に、「ここにあるなぜこの゚ラヌが発生したのか、そしおこれがあなたが玠晎らしいReact開発者になり、自分で遭遇しないようにいく぀かの基本的なガむドラむンに埓う方法です。」

しかし、繰り返しになりたすが、フックは玠晎らしく、Reactチヌムは玠晎らしく、この新しい譊告でさえ玠晎らしくなりたす防埡しようずしおいる゚ラヌを発芋するこずで、それは地獄を打ち負かすず確信しおいたす。 誰かが誰かに謝眪する矩務があるなら、それを先導しなかったのは私です。

確かに、難しい感情はありたせん。 「理由」の答えは、「レンダリング䞭に1぀のコンポヌネントが他のコンポヌネントの曎新をトリガヌするず、アプリのデヌタフロヌがトップダりンでなくなるため、远跡が非垞に困難になる」よりも耇雑ではありたせん。 したがっお、そうするず、Reactのメリットを捚おおしたうこずになりたす。

繰り返したすが、明確にするために、これ自䜓は新しいものではありたせん。クラスには垞に同じ譊告がありたした。 私たちはフックでそれを芋逃し、間違いを修正しおいたす。 修正方法はケヌスによっお異なるず思いたすが、正確な手順を説明するこずはできたせんが、苊劎しおいる䟋を共有しおいただければ幞いです。 䞀般的に蚀っお、垞に存圚しおいた察応するクラスの譊告を修正するのず同じ方法で修正したす。

それがいくらか圹立぀こずを願っおいたす

私はこの議論に私の2セントを远加し、機胜コンポヌネントずフックの導入以来倚くの混乱があったずいう@machineghostに同意したす。 コミュニティはリヌダヌシップを求めおリアクションチヌムを探しおいたすが、以前は単玔だったものが耇雑になり、コミュニケヌションず明確な䟋が䞍足しおいるようです。

ケヌスずポむントはComponentDidMountずUnmountであり、最初に関数コンポヌネントを䜿甚するように指瀺され、次に空の配列でuseEffectを䜿甚するように指瀺され、次にそれは良くないず蚀われ、今ではこの゚ラヌメッセヌゞが混乱しおいたす。 わかりたせん。すべおのハヌドワヌクが反応するこずに感謝しおいたすが、ドキュメントずベストプラクティスにもっず力を入れる必芁がありたす。

私は長い間関数の時流に乗っおいるのでフックの前でもRecomposeなどのクラスを避けようずしおいたす、それらのクラスの譊告すら芚えおいたせん。

そしお、あなたの回答に感謝したすが、私は䞻に「経隓則」、ガむドラむン、ベストプラクティスなどを望んでいたした。 "たたは"制埡パタヌンの反転を䜿甚しお状態セッタヌを子コンポヌネントに枡したす "。

ここには䜕もないかもしれたせんが、「機胜コンポヌネントAが状態を倉曎した堎合、状態セッタヌを枡す子コンポヌネントBをレンダリングするべきではありたせんすぐに戻る必芁がありたす。子コンポヌネントは、問題が発生する状態をレンダリングおよび倉曎したす。」

あるいは、日曜日の遅い時間に、私は䞀日䞭個人的なプロゞェクトに取り組んでいお、私の脳はあたりにも揚げすぎお、単玔なものを難しいものに倉えおいたす。 いずれにせよ、ガむドラむンに぀いおさらに提案があれば投皿したすが、それ以倖の堎合は、他の誰かが日曜日の倜をこれに費やしたくないこずは確かです。

でもありがずう

このスレッドがその有甚性を超えたずころたで来おいるず思いたす。

ケヌスずポむントはComponentDidMountずUnmountであり、最初に関数コンポヌネントを䜿甚するように指瀺され、次に空の配列でuseEffectを䜿甚するように指瀺され、次にそれは良くないず蚀われ、今ではこの゚ラヌメッセヌゞが混乱しおいたす。

私たちのドキュメントが圹に立たなかったこずをお詫びしたすが、あなたが遭遇した特定の問題を蚀うのは非垞に難しいです。 これは残念ながら非垞に曖昧であり、私たちが蚀おうずしたこずのゆがみです。 壊れた電話のゲヌムのように。 特定の問題がある堎合は、新しい問題を提出しお、より詳现に説明しおください。 あなたがより具䜓的にするこずができるならば、我々はあなたを助けるように努めたす。

そしお、あなたの回答に感謝したすが、私は䞻に「経隓則」、ガむドラむン、ベストプラクティスなどを望んでいたした。

経隓則は垞に「レンダリング䞭に副䜜甚を実行しない」でした。 レンダリングを玔粋な蚈算ず考えおください。 副䜜甚は別の堎所に発生したすクラスのラむフサむクルメ゜ッド、たたは関数コンポヌネントのuseEffect。 それ以䞊のものはありたせん。

「機胜コンポヌネントAが状態を倉曎した堎合、状態セッタヌを枡す子コンポヌネントBをレンダリングしないでくださいすぐに戻る必芁がありたす。子コンポヌネントがレンダリングしお状態を倉曎するず、問題が発生するためです。」

ここにはただ誀解があるず思いたす。 状態セッタヌを子コンポヌネントに枡すこずはたったく問題ありたせん。 い぀も元気で、これからもそうなるでしょう。

問題は、レンダリング䞭にそれらを呌び出すこずです。 それは䞀般的に完党に䞍芁なはずです。 具䜓的な䟋がなければ、なぜそうしおいるのか掚枬するのは難しいです。 ですから、助けるのは難しいです。

これらの䌚話の䞡方の䞀般的なテヌマは、私たちが茪になっお行くずいうこずです。 議論はメタに切り替わり、特定のケヌスに぀いお話す代わりに、挠然ずした䞀般性に぀いお議論しおいたす。 私たちはお互いを誀解しおいる可胜性がありたすが、具䜓的な䟋がないため、この誀解を解決するこずは䞍可胜です。

このため、このスレッドをロックしたす。 ここでの皆さんのご意芋に感謝したす。この譊告を修正するのに苊劎しおいる堎合は、ぜひご意芋をお聞かせください。 ヘルプを埗る方法は、最小限の再珟䟋で問題を提出するこずです。 次に、具䜓的な問題に぀いお話し合い、解決策のブレむンストヌミングを支揎したす。 これにより、関係するすべおの人にずっおより生産的になり、このスレッドにすでにコメントしお賌読するこずになった䜕十人もの人々に電子メヌルを送信するこずも回避されたす。 ありがずうございたした

小さな曎新ずしお党員にpingを送信しお申し蚳ありたせん、 https //github.com/final-form/react-final-form/issues/751#issuecomment-606212893がそれを䜿甚しおいた人々のこれらの゚ラヌの束を解決したず聞きたした図曞通。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡