Conditionally calling a hook in react

There is a rule in react about not calling a hook conditionally. AFAIK react only cares about the number of hooks called, so I tried this:

function useMainHook({ isLive }) {
  const res = isLive ? useHookA() : useHookB();
  return res;  // Make sure to return the result
}

If react only cares about how many hooks are called, this should work. Since there is always 1 hook being called.

Is the hook definition above valid?

0

react only cares about the number of hooks called

React doesn’t care about the number of hooks in it’s own sake. React cares about the number of hooks because all hooks (within one component) need to be called in the same order for every render. Thus disallowing conditional hooks.

If we run the below example we see that valueB is 0, although it should be 10. That is because both valueA and valueB are the second useState within App and so React can’t distinguish them.

import { useEffect, useState } from "react";

const useHookA = () => {
  const [valueA] = useState(0);
  console.log("hook a", valueA);
  return valueA;
}

const useHookB = () => {
  const [valueB] = useState(10);
  console.log("hook b", valueB);
  return valueB;
}

function App() {
  const [hookA, setHookA] = useState(true);
  useEffect(() => {
    const i = setInterval(() => setHookA(v => !v), 1000);
    return () => clearInterval(i);
  }, []);

  const value = hookA ? useHookA() : useHookB();

  return (
    <p>Hook {hookA ? "A" : "B"}, value: {value}</p>
  );
}

2

function useMainHook({ isLive }) {
  const res = isLive ? useHookA() : useHookB();
  return res;  // Make sure to return the result
}

If React only cares about how many hooks are called, this should work.
Since there is always 1 hook being called.

Is the hook definition above valid?

I’m inclined to say no, this is not a valid usage/definition.

This code may work, but only as a special case and not as a general rule. It depends entirely on what useHookA and useHookB actually do, it’s not just what hooks are called right there in the one component/useMainHook hook. All React hooks from all rendered components in the ReactTree are called each and every render cycle.

Consider the following two counter examples:

const useHookA = () => {
  React.useEffect(() => {
    console.log("A effect 1");
  });
  React.useEffect(() => {
    console.log("A effect 2");
  });
};

const useHookB = () => {
  React.useEffect(() => {
    console.log("B");
  });
};

function App() {
  const [state, setState] = React.useState(false);

  state ? useHookA() : useHookB();

  const toggleState = () => setState((b) => !b);

  return (
    <div className="App">
      <button type="button" onClick={toggleState}>
        Toggle
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
<div id="root" />
const useHookA = () => {
  const [stateA, setStateA] = React.useState("a");

  React.useEffect(() => {
    console.log("A");
  });
};

const useHookB = () => {
  React.useEffect(() => {
    console.log("B");
  });
};

function App() {
  const [state, setState] = React.useState(false);

  state ? useHookA() : useHookB();

  const toggleState = () => setState((b) => !b);

  return (
    <div className="App">
      <button type="button" onClick={toggleState}>
        Toggle
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
<div id="root" />

Your implementation breaks React’s Rules of Hooks.

Don’t call Hooks inside loops, conditions, nested functions, or
try/catch/finally blocks. Instead, always use Hooks at the top
level of your React function, before any early returns. You can only
call Hooks while React is rendering a function component:

  • ✅ Call them at the top level in the body of a function component.
  • ✅ Call them at the top level in the body of a custom Hook.

It’s not supported to call Hooks (functions starting with use) in
any other cases, for example:

  • 🔴 Do not call Hooks inside conditions or loops.
  • 🔴 Do not call Hooks after a conditional return statement.
  • 🔴 Do not call Hooks in event handlers.
  • 🔴 Do not call Hooks in class components.
  • 🔴 Do not call Hooks inside functions passed to useMemo, useReducer, or
    useEffect.
  • 🔴 Do not call Hooks inside try/catch/finally blocks.

You can re-write your implementation to not break React’s Rules of Hooks.

Example: Unconditionally call all hooks and then conditionally return the expected result.

function useMainHook({ isLive }) {
  const resA = useHookA();
  const resB = useHookB();
  return isLive ? resA : resB;
}

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật