最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Why is the effect not called twice in strict mode? - Stack Overflow

programmeradmin0浏览0评论

I was walking through some code and came across the following snippet to prevent StrictMode from calling an effect twice. While it's generally not recommended to implement such a feature, I was more confused on why it actually works. See the following:

export const useApiDemo = (param: string) => {
  let strictModeRerun = false;

  useEffect(() => {
    !strictModeRerun && fetchApi(param);
    return () => {
      strictModeRerun = true;
    };
  }, [param]);
};

As I understand in strictmode hooks and components get called twice so we can identify any misconfigurations or faulty cleanups. If useApiDemo (or the component it's used in) renders twice, I would assume strictModeRerun would also be false twice because it's defined inline in the render scope. It is not persisted between renders so I would assume this causes the second run to also call the api. However the api call is only fired once. If I remove the strictModeRerun the api does fire twice. Why does this actually work?

I was walking through some code and came across the following snippet to prevent StrictMode from calling an effect twice. While it's generally not recommended to implement such a feature, I was more confused on why it actually works. See the following:

export const useApiDemo = (param: string) => {
  let strictModeRerun = false;

  useEffect(() => {
    !strictModeRerun && fetchApi(param);
    return () => {
      strictModeRerun = true;
    };
  }, [param]);
};

As I understand in strictmode hooks and components get called twice so we can identify any misconfigurations or faulty cleanups. If useApiDemo (or the component it's used in) renders twice, I would assume strictModeRerun would also be false twice because it's defined inline in the render scope. It is not persisted between renders so I would assume this causes the second run to also call the api. However the api call is only fired once. If I remove the strictModeRerun the api does fire twice. Why does this actually work?

Share Improve this question edited 22 hours ago Drew Reese 204k18 gold badges244 silver badges273 bronze badges asked yesterday KipnoedelsKipnoedels 1,4061 gold badge11 silver badges28 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

React 18 has a few dev only quirks. The two we are concerned with here are:

  1. Double rerendering of components.
  2. Double running of effects.

They are independent. For example:

let renderCount = 0;
export default function ChatRoom() {
  let strictModeRerun = false;

  // // let strictModeRerun = false;
  renderCount++;
  console.log("rerender", renderCount);

  useEffect(() => {
    console.log("connect", strictModeRerun);
    let connect = null;
    if (!strictModeRerun) {
      connection = createConnection(serverUrl, roomId);
      connection.connect();
    }

    return () => {
      strictModeRerun = true;
      connection?.disconnect();
    };
  }, []);
  return <h1>Welcome to the {roomId} room!</h1>;
}

The output of the above components rendering in the log is:

This proves that first the double render happens. And only after that the effect runs. Anyway the effect is supposed to run right before painting.

Sandbox Link

rerender is logged twice with both the values of renderCount. And then the effect run. Since you are setting the value false, it never runs again as you had imagined.

发布评论

评论列表(0)

  1. 暂无评论