🕌

Reactアンチパターン(PART1)

2023/12/17に公開

このコードの問題点がわかりますか?


interface GrandchildComponentProps {
  active: boolean;
  setActive: React.Dispatch<React.SetStateAction<boolean>>;
}

const GrandchildComponent: FC<GrandchildComponentProps> = ({ active, setActive }) => {
  return (
    <div>
      <p>Active state in Grandchild: {active.toString()}</p>
      <button onClick={() => setActive(!active)}>Toggle Active</button>
    </div>
  );
};

interface ChildComponentProps {
  active: boolean;
  setActive: React.Dispatch<React.SetStateAction<boolean>>;
}

const ChildComponent: FC<ChildComponentProps> = ({ active, setActive }) => {
  return (
    <div>
      <p>Active state in Child: {active.toString()}</p>
      <GrandchildComponent active={active} setActive={setActive} />
    </div>
  );
};

const ParentComponent: FC = () => {
  const [active, setActive] = useState(false);

  return (
    <div>
      <p>Active state in Parent: {active.toString()}</p>
      <ChildComponent active={active} setActive={setActive} />
    </div>
  );
};

export default ParentComponent;

上記のコードは状態管理をバケツリレーしてしまっている。
親→子→孫にかけて、active、setActiveを渡している。
propsの型も汚れるし、修正も大変になっている。
よくredux等を使う判断に大規模アプリなどだと〜みたいなことが言われるが、
小規模だろうが大規模だろうが個人的に下記のような状況になるくらいなら、最初からreduxを使うべき!
下記の様に修正してください!

// GrandchildComponent.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { toggleActive } from './actions';

const GrandchildComponent = () => {
  const active = useSelector((state) => state.active);
  const dispatch = useDispatch();

  return (
    <div>
      <p>Active state in Grandchild: {active.toString()}</p>
      <button onClick={() => dispatch(toggleActive())}>Toggle Active</button>
    </div>
  );
};

export default GrandchildComponent;

親も子も同様です!

Discussion