import { jsx, jsxs, Fragment } from 'solid-jsx/jsx-runtime';

/*@jsxRuntime automatic @jsxImportSource solid-jsx*/
const toc = [];
function _createMdxContent(props) {
  const _components = Object.assign({
    p: "p",
    code: "code",
    pre: "pre",
    span: "span"
  }, props.components);
  return jsxs(Fragment, {
    children: [jsx(_components.p, {
      children: "ストアは多くの場合、Solid のストアプロキシを使用して Solid で作成されます。時には、Redux、Apollo、XState などのイミュータブルなライブラリとインターフェイスでつなぎ、これらに対して粒度の高い更新を行う必要があります。"
    }), "\n", jsxs(_components.p, {
      children: ["この例では、Redux の基本的なラッパーを用意しています。その実装は ", jsx(_components.code, {
        children: "useRedux.tsx"
      }), " で見ることができます。ストアの定義とアクションは残りのファイルにあります。"]
    }), "\n", jsx(_components.p, {
      children: "中心となる動作は、Store オブジェクトを作成し、Redux のストアを購読して、更新時に状態を更新するというものです。"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [state, setState] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createStore"
        }), "(store.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getState"
        }), "());\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " unsubscribe = store.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "subscribe"
        }), "(\n  ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setState"
        }), "(store.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getState"
        }), "())\n);\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "デモをクリックしてアイテムを追加したり、チェックしたりすると、かなりうまくいっているように見えます。しかし、明白でないのは、レンダリングが非効率的であるということです。作成時だけでなく、ボックスをチェックするたびに console.log が表示されていることに注目してください。"
    }), "\n", jsx(_components.p, {
      children: "その理由は、Solid はデフォルトでは差分を取らないためです。新しいアイテムを新しいものとみなして置き換えてしまうのです。データが細かく変化する場合は、差分を取る必要はありません。しかし、もしやる場合は？"
    }), "\n", jsxs(_components.p, {
      children: ["Solid は差分を取るためのメソッド ", jsx(_components.code, {
        children: "reconcile"
      }), " を提供しています。これは ", jsx(_components.code, {
        children: "setStore"
      }), " の呼び出しを強化するもので、イミュータブルなソースからのデータを差分して、細かい更新のみを通知できます。"]
    }), "\n", jsx(_components.p, {
      children: "では、このコードを次のように更新してみましょう:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [state, setState] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createStore"
        }), "(store.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getState"
        }), "());\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " unsubscribe = store.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "subscribe"
        }), "(\n  ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setState"
        }), "(", jsx(_components.span, {
          className: "hljs-title function_",
          children: "reconcile"
        }), "(store.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getState"
        }), "()))\n);\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "これで、この例は期待通りに動作し、作成時にだけ create のコードを実行ようになりました。"
    }), "\n", jsxs(_components.p, {
      children: ["これはこの問題を解決する唯一の方法ではなく、一部のフレームワークでテンプレートループフローに ", jsx(_components.code, {
        children: "key"
      }), " プロパティがあるのを見たことがあるでしょう。問題は、それをテンプレートのデフォルト部分にすることにより、コンパイル済みのフレームワークであっても、リストの一致を常に実行する必要があり、潜在的な変更のためにすべての子の差分を常に取る必要があることです。データ中心のアプローチでは、テンプレートの外でもこれを適用できるだけでなく、オプトインもできます。内部の状態管理にはこれが必要ないことを考える場合、デフォルトで最高のパフォーマンスが得られることになります。"]
    }), "\n", jsxs(_components.p, {
      children: ["もちろん、必要に応じて ", jsx(_components.code, {
        children: "reconcile"
      }), " を使うことは問題ありません。シンプルな reducer がデータの更新を整理するのに最適な方法であることもあります。", jsx(_components.code, {
        children: "reconcile"
      }), " は、独自の ", jsx(_components.code, {
        children: "useReducer"
      }), " プリミティブを作ることで、ここで威力を発揮します:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "useReducer"
        }), " = (", jsx(_components.span, {
          className: "hljs-params",
          children: "reducer, state"
        }), ") => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [store, setStore] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createStore"
        }), "(state);\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispatch"
        }), " = (", jsx(_components.span, {
          className: "hljs-params",
          children: "action"
        }), ") => {\n    state = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "reducer"
        }), "(state, action);\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setStore"
        }), "(", jsx(_components.span, {
          className: "hljs-title function_",
          children: "reconcile"
        }), "(state));\n  }\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " [store, dispatch];\n};\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "reconcile"
      }), " の動作は設定可能です。カスタムの ", jsx(_components.code, {
        children: "key"
      }), " を設定ができ、構造的に複製することを無視して葉ノードのみを差分する ", jsx(_components.code, {
        children: "merge"
      }), " オプションもあります。"]
    })]
  });
}
function MDXContent(props = {}) {
  const {wrapper: MDXLayout} = props.components || ({});
  return MDXLayout ? jsx(MDXLayout, Object.assign({}, props, {
    children: jsx(_createMdxContent, props)
  })) : _createMdxContent(props);
}

export { MDXContent as default, toc };
//# sourceMappingURL=lesson-ae4be532.js.map
