ホームページ  >  に質問  >  本文

React.useCallback を別の React.useCallback 内で使用できますか?

<p>汚れ用のカップ写真のコンポーネントが 1 つあります</p> <p> <pre class="brush:js;toolbar:false;">React を "react" からインポートします。 const User = React.memo(function({id, name, isSelected, ...other}) { 戻る ( <div {...other}> {名前} - {isSelected && 「選択済み」} </div> ); }); デフォルトのユーザーをエクスポート;</pre> </p> <p>および渲染用户卡の父構成要素</p> <p> <pre class="brush:js;toolbar:false;">React を "react" からインポートします。 関数アプリケーション() { const [users, setUsers] = React.useState([ {id: 1、名前: "ジョン ドゥ #1"}、 {id: 2、名前: "ジョン ドゥ #2"}、 {id: 3、名前: "ジョン ドゥ #3"} ]); const [selectedUserId, setSelectedUserId] = React.useState(null); return users.map((user) => { const isSelected = selectedUserId === user.id; 戻る ( <ユーザー {...ユーザー} key={ユーザーID} isSelected={isSelected} onClick={() => setSelectedUserId(user.id)} /> ); }); } デフォルトのアプリケーションをエクスポート;</pre> </p> <p>任務は「ユーザーを選択した後、他のユーザーの再汚染を避ける」</p> <p>我尝试は <code>React.useCallback</code> を使用します。钩子、これは我の第一实现</p> <p> <pre class="brush:js;toolbar:false;">React を "react" からインポートします。 const User = React.memo(function({id, name, isSelected, ...other}) { 戻る ( <div {...other}> {名前} - {isSelected && 「選択済み」} </div> ); }); 関数アプリケーション() { const [users, setUsers] = React.useState([ {id: 1、名前: "ジョン ドゥ #1"}、 {id: 2、名前: "ジョン ドゥ #2"}、 {id: 3、名前: "ジョン ドゥ #3"} ]); const [selectedUserId, setSelectedUserId] = React.useState(null); const handleSelectUser = React.useCallback((userId) => () => { setSelectedUserId(userId); }、[]); return users.map((user) => { const isSelected = selectedUserId === user.id; 戻る ( <ユーザー {...ユーザー} key={ユーザーID} isSelected={isSelected} onClick={handleSelectUser(user.id)} /> ); }); } デフォルトのアプリケーションをエクスポート;</pre> </p> <p>この場合、<code>React.useCallback</code> は新しい参照を含む匿名関数を返します</p> <p><strong>結果: すべてのユーザー カードは、クリックするたびに再レンダリングされます</strong></p> <p>この匿名関数を <code>React.useCallback</code></p> でラップすることにしました。 <p> <pre class="brush:js;toolbar:false;">React を "react" からインポートします。 const User = React.memo(function({id, name, isSelected, ...other}) { 戻る ( <div {...other}> {名前} - {isSelected && "選択済み"} </div> ); }); 関数アプリケーション() { const [users, setUsers] = React.useState([ {id: 1、名前: "ジョン ドゥ #1"}、 {id: 2、名前: "ジョン ドゥ #2"}、 {id: 3、名前: "ジョン ドゥ #3"} ]); const [selectedUserId, setSelectedUserId] = React.useState(null); const handleSelectUser = React.useCallback((userId) => { return React.useCallback(() => { setSelectedUserId(userId); }、[]); }、[]); return users.map((user) => { const isSelected = selectedUserId === user.id; 戻る ( <ユーザー {...ユーザー} key={ユーザーID} isSelected={isSelected} onClick={handleSelectUser(user.id)} /> ); }); } デフォルトのアプリケーションをエクスポート;</pre> </p> <p>問題は解決しましたが、まだ疑問が 1 つあります。正しくできましたか? React チームは次のように述べています: <em>ループ、条件分岐、またはネストされた関数内でフックを呼び出さない</em>どのような副作用が発生しますか? </p> <p><code>user</code>コンポーネント</p>には触れないでください。
P粉153503989P粉153503989387日前520

全員に返信(1)返信します

  • P粉810050669

    P粉8100506692023-09-02 12:43:37

    フック内からフックを呼び出すことができない理由を説明します (そして、フックが一貫して確実に機能することを期待します)

    フック内でフックを呼び出すことができない理由 - この回答で提供する必要がある以上のコンテキストを含む超詳細な説明については、ここを参照してください https://overreacted.io/why-do-hooks -呼び出し順序に依存/

    「ルールに違反している」にもかかわらず、ユーザーが状態に追加または削除されるまで、フックへの呼び出しの順序は常に同じであるため、ソリューションは機能します。

    あなたが書いたソリューションは間違いなく使用できます。しかし、ユーザー数を変更する必要がある場合はどうすればよいでしょうか?


    いいえ、フックの中でフックを使用することはできません。それは「機能する」かもしれませんが、React はそれが確実に機能しないこと、そしてやり方が間違っていることを伝えています。フックは、カスタム フックの最上位コンポーネントの最上位で呼び出す必要があります。

    あなたの方向性は正しいですが、問題の解決策は

      コールバック関数に提供されたパラメータをクリックされた要素のソースとして使用し、かつ
    1. User コンポーネントを変更できない場合は、どの user 要素がクリックされたかを示すために、
    2. div 要素にデータを提供する必要があります。
    次のようになります:

    リーリー

    返事
    0
  • キャンセル返事