const App = () => {
  const [count, setCount] = useState(0);
  return <h1 onClick={() => setCount(count + 1)}>{count}</h1>;
};const initialState = { count: 0 };
function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}
function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
    </>
  );
}import { createContext, useContext } from "react";
const Context = createContext({ theme: "light" });
const Child = () => {
  const { theme } = useContext(Context);
  return <>{theme}</>;
};
const Parent = () => {
  return <Child />;
};
const App = () => {
  return (
    <Context.Provider value={{ theme: "dark" }}>
      <Parent />
    </Context.Provider>
  );
};
export default App;const App = () => {
  useEffect(() => {
    console.log(111);
  }, []);
  return <div>title</div>;
};const App = () => {
  useLayoutEffect(() => {
    console.log(111);
  }, []);
  return <div>title</div>;
};const App = () => {
  useInsertionEffect(() => {
    console.log(111);
  }, []);
  return <div>title</div>;
};import { useRef, forwardRef } from "react";
const Child = forwardRef((props: any, ref: any) => {
  return <input ref={ref} />;
});
const Parent = () => {
  const inputRef = (useRef < HTMLInputElement) | (null > null);
  const onClick = () => {
    if (inputRef.current) {
      inputRef.current.value = "reset";
    }
  };
  return (
    <>
      <Child ref={inputRef} />
      <button onClick={onClick}>reset</button>
    </>
  );
};
const App = () => {
  return <Parent />;
};
export default App;const App = () => {
  const title = useMemo(() => "dao", []);
  return <div>{title}</div>;
};const App = () => {
  const setTitle = useCallback(() => {
    console.log(111);
  }, []);
  return (
    <button
      type="button"
      onClick={setTitle}
    >
      +
    </button>
  );
};const App = () => {
  const [value, setValue] = useState("");
  const [isPending, startTransition] = useTransition();
  const onChange = (e: ChangeEvent<HTMLInputElement>) => {
    // 긴급처리건.
    setValue(e.target.value);
    startTransition(() => {
      // 후순위 처리.
      setContent(e.target.value);
    });
  };
  return (
    <>
      <input
        value={value}
        onChange={onChange}
      />
      <div>{value.length}</div>
    </>
  );
};const App = () => {
  const [value, setValue] = useState("");
  const lowValue = useDeferredValue(value.length);
  const onChange = (e: ChangeEvent<HTMLInputElement>) => {
    setValue(e.target.value);
  };
  return (
    <>
      <input
        value={value}
        onChange={onChange}
      />
      <div>{lowValue}</div>
    </>
  );
};// todoStore.js
let nextId = 0;
let todos = [{ id: nextId++, text: "Todo #1" }];
let listeners = [];
export const todosStore = {
  addTodo() {
    todos = [...todos, { id: nextId++, text: "Todo #" + nextId }];
    emitChange();
  },
  subscribe(listener) {
    listeners = [...listeners, listener];
    return () => {
      listeners = listeners.filter((l) => l !== listener);
    };
  },
  getSnapshot() {
    return todos;
  },
};
function emitChange() {
  for (let listener of listeners) {
    listener();
  }
}
// App.jsx
const App = () => {
  const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot);
  return (
    <>
      <button onClick={todosStore.addTodo}>Add todo</button>
      <hr />
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </>
  );
};// 여러번 불러오는 컴포넌트일 경우 아래와 같이 필요함.
const App = () => {
  const inputId = useId();
  return (
    <>
      <input id={`${inputId}-firstName`} />
      <input id={`${inputId}-lastName`} />
    </>
  );
};
// ssr일경우 생성한 id가 다른경우가 있음.
// 1. 서버단 생성시 id="1" 생성
// 2. <div id="1"></div>을 client에게 전달
// 3. csr랭딩시 hydrate를 통해서 id="2" 로 처리.