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: "Stores are most often created in Solid using Solid's Store proxies. Sometimes we wish to interface with immutable libraries like Redux, Apollo, or XState and need to perform granular updates against these."
    }), "\n", jsxs(_components.p, {
      children: ["In the example, we have a basic wrapper around Redux. You can see the implementation in ", jsx(_components.code, {
        children: "useRedux.tsx"
      }), ". The definition of the store and the actions are in the remaining files."]
    }), "\n", jsx(_components.p, {
      children: "The core behavior is that we created a Store object and subscribe to the Redux store to update state on update."
    }), "\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: "If you click around the demo adding items and checking them off it seems to work pretty well. However, what isn't obvious is that the rendering is inefficient. Notice the console.log not only on create but whenever you check the box."
    }), "\n", jsx(_components.p, {
      children: "The reason is that Solid doesn't diff by default. It assumes the new item is new and replaces it. If your data changes granularly, you don't need to diff. But what if you do?"
    }), "\n", jsxs(_components.p, {
      children: ["Solid provides a diffing method ", jsx(_components.code, {
        children: "reconcile"
      }), " that enhances the ", jsx(_components.code, {
        children: "setStore"
      }), " call and lets us diff the data from these immutable sources, only notifying the granular updates."]
    }), "\n", jsx(_components.p, {
      children: "Let's update that code to:"
    }), "\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: "Now the example works as you'd expect, only running the create code on create."
    }), "\n", jsxs(_components.p, {
      children: ["This isn't the only way to solve this and you've seen some frameworks have a ", jsx(_components.code, {
        children: "key"
      }), " property on their template loop flows. The problem is that by making that a default part of the templating, you always need to run list reconciliation and always have to diff all the children for potential changes, even in compiled frameworks. A data-centric approach not only makes this applicable outside of templating but makes it opt in. When you consider that internal state management doesn't need this, it means we default to having the best performance."]
    }), "\n", jsxs(_components.p, {
      children: ["Of course, there's no problem using ", jsx(_components.code, {
        children: "reconcile"
      }), " when you need it. Sometimes a simple reducer makes for a great way to organize data updates. ", jsx(_components.code, {
        children: "reconcile"
      }), " shines here, making your own ", jsx(_components.code, {
        children: "useReducer"
      }), " primitive:"]
    }), "\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: ["The behavior of ", jsx(_components.code, {
        children: "reconcile"
      }), " is configurable. A custom ", jsx(_components.code, {
        children: "key"
      }), " can be set and there is a ", jsx(_components.code, {
        children: "merge"
      }), " option which ignores structural cloning and only diffs the leaves."]
    })]
  });
}
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-94b6d1fe.js.map
