Skip to content

Instantly share code, notes, and snippets.

@JoviDeCroock
Last active May 8, 2021 06:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8 to your computer and use it in GitHub Desktop.
Save JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8 to your computer and use it in GitHub Desktop.

Strict-equality

When creating elements and passing them as children we can have scenario's where we don't have to diff the children because it will still be the same vnode.

Imagine the following scenario:

const context = createContext(null);
const App = () => (
  <Layout>
    <MyPage />
  </Layout>
);

const Layout = (props) => {
  const [state, setState] = useState(false);
  return (
    <context.Provider value={{ state, setState }}>
      {props.children}
    </context.Provider>
  );
}

const MyPage = () => {
  const [state, setState] = useState(false);
  return (
    <MyConsumer state={state} />
  );
}

const MyConsumer = () => {
  const { state, setState } = useContext(context);
  return <p>{state}</p>
};

When Layout updates due to a setState the diff should not continue to MyPage since this createElement call is from App and this will still be the same vnode so for the sake of Layout this doesn't matter.

When due to Preact-batching we would have a queue of [Layout, MyConsumer], this could be caused by two subsequent setState calls we have to be careful, our current diffing algorithm will bail out due to children being equal (this check). In this case we have to be careful not to indicate the child as not dirty (a state update dirties a component). This is a bailout case we have to add for this to work (bailout).

This optimization is important for context-propagation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment