shige8
@shige8

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

[ReactNative]useEffect内でfor文のループが行われない

解決したいこと

服薬習慣化アプリを作っています。

useEffect内でfor文を使っているのですが、ループが行われません。

発生している問題

  const [meds, setMeds] = useState([]);
  const [days, setDays] = useState(0);

medsには別のuseEffectから代入した下記の配列が入っています。

Array [
  2022-04-18T00:00:00.000Z,
  2022-04-17T00:00:00.000Z,
  2022-04-16T00:00:00.000Z,
  2022-04-15T00:00:00.000Z,
  2022-04-14T00:00:00.000Z,
  2022-04-13T00:00:00.000Z,
  2022-04-12T00:00:00.000Z,
  2022-04-11T00:00:00.000Z,
  2022-04-10T00:00:00.000Z,
  2022-04-08T00:00:00.000Z,
  2022-04-07T00:00:00.000Z,
  2022-04-06T00:00:00.000Z,
  2022-04-05T00:00:00.000Z,
  2022-04-04T00:00:00.000Z,
]
import { subDays } from "date-fns";

 useEffect(() => {
    for (let i = 0; i < meds.length; i++) {
      if (meds[i + 1] === subDays(meds[i], 1)) {
          setDays(days + 1);
      } else {
        break;
      }
    }
  }, [])

連続した日数だけdaysに加算したいのですが、if文を消しても、1しか表示されません。

また、

console.log(subDays(meds[0],1));
console.log(meds[1]);

2022-04-17T00:00:00.000Z
2022-04-17T00:00:00.000Z

となるのですが、上記の条件式ではsetDays(days + 1);がうまくいかず、0となります。

return (
      <Text style={styles.text}>{days}</Text>
)

ReactNativeの知識が浅く、解決できません。ヒントでも良いのでいただけたら幸いです。

0

2Answer

useState()の仕様の問題だと思います。
 うろ覚えですが確かuseStateのステート更新が行われえるのが、その関数コンポーネントの関数が実行し終わったときです。
 ということは同じ関数内で何度もuseStateのステートを変更しても、一度しか変更されてないのと同じ状況になるということです。

 書き方は忘れてしまったのですが、ステートをしっかり更新する書き方があったはずなので調べてみてください(^▽^)/

0Like

Comments

  1. @shige8

    Questioner

    @OyaTomoさん
    回答ありがとうございます。Stateの更新の問題なんですね!
    調べてみます!

setDays() を呼んでもその場で days の値が変わることはありません。関数コンポーネントが次に実行されたときに初めて反映されます。よって、 for ループの中で何度 setDays(days + 1) を呼んでも(初回のレンダリングなら days == 0 なので) setDays(0 + 1) するのと同じです。

最新の state の値を使って計算したいなら、以下のように setDays() に更新用関数を渡してください。

 useEffect(() => {
    for (let i = 0; i < meds.length; i++) {
      if (meds[i + 1] === subDays(meds[i], 1)) {
        setDays((d) => d + 1);
      } else {
        break;
      }
    }
  }, []);

参考:

0Like

Comments

  1. @shige8

    Questioner

    @uasiさん
    回答ありがとうございます。
    教えていただいた更新用関数でうまく行きました!ありがとうございます!
    ただ、条件式の meds[i + 1] === subDays(meds[i], 1) が上手くいきません。
    new Date()で比較してもダメです。
    何かヒントありましたらご教授ください。
  2. @shige8

    Questioner

    @uasiさん
    条件式の meds[i + 1] === subDays(meds[i], 1) ですが、
    const m1 = new Date(meds[i + 1]).getTime();
    const m2 = new Date(subDays(meds[i], 1)).getTime();
    でうまくいきました!
    ありがとうございます!

Your answer might help someone💌