在使用Reduxstore 时,我在Reaction组件中遇到了重新渲染的问题. 我使用的是功能组件.

以下是应该重新呈现的我的App.js

import Habbit from "./Habbit";
import NavBar from "./NavBar";
import HabitTrackerWeekView from "./HabitTrackerWeekView";
import { switchComponents, addHabit } from "../Action";
import { useEffect, useState } from "react";

function App({ store }) {
  const [newHabit, setNewHabit] = useState("");
  const { habitList, switchCom, currentMonth, doneCount } = store.getState();
  useEffect(() => {
    console.log("app.js done count ", doneCount);
  }, [doneCount]);


  return (
    <div className="App">
      <NavBar />
      <HabitTrackerWeekView
        habits={store.getState()}
        dispatch={store.dispatch}
        currentMonth={currentMonth}
      />
    </div>
  );
}

export default App;

这是我的HabitTrackerWeekView.js,其中DONDONCOUNT将发送到Reduxstore

import React, { useEffect, useReducer, useState } from "react";
import { countDoneStatuses } from "../Action";
import {
  format,
  subWeeks,
  startOfWeek,
  endOfWeek,
  eachDayOfInterval,
  addWeeks,
} from "date-fns";

function HabitTrackerWeekView({ habits, dispatch }) {
  const { habitList } = habits;
  const [currentMonth, setCurrentMonth] = useState(new Date());
  const [habitStatuses, setHabitStatuses] = useState({});
  const [habitDoneCounts, setHabitDoneCounts] = useState(
    habitList.reduce((counts, habit) => ({ ...counts, [habit]: 0 }), {})
  );
  useEffect(() => {
    // console.log("Current habitDoneCounts:", habitDoneCounts);
    dispatch(countDoneStatuses(habitDoneCounts));
  }, [habitDoneCounts]);

  const weekdays = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
  ];
  const getCurrentWeekDates = () => {
    const startOfCurrentWeek = startOfWeek(currentMonth, { weekStartsOn: 1 });
    const endOfCurrentWeek = endOfWeek(currentMonth, { weekStartsOn: 1 });
    const datesOfCurrentWeek = eachDayOfInterval({
      start: startOfCurrentWeek,
      end: endOfCurrentWeek,
    });
    const formattedDatesOfCurrentWeek = datesOfCurrentWeek.map((date) =>
      format(date, "dd")
    );

    return formattedDatesOfCurrentWeek;
  };
  const dates = getCurrentWeekDates();
  const handlePreviousWeek = () => {
    setCurrentMonth(subWeeks(currentMonth, 1));
  };

  const getMonthYear = () => {
    const dateFormat = "MMM yyyy";
    return format(currentMonth, dateFormat);
  };

  const handleNextWeek = () => {
    setCurrentMonth(addWeeks(currentMonth, 1));
  };

  const handleTodaysStatus = (date, habit) => {
    const key = `${date}-${habit}`;
    setHabitStatuses((prevStatuses) => {
      const currentStatus = prevStatuses[key] || "none";

      const newStatus =
        currentStatus === "none"
          ? "done"
          : currentStatus === "done"
          ? "not done"
          : "none";
      setHabitDoneCounts((prevCounts) => ({
      ...prevCounts,
      [habit]:
        newStatus === "done"
          ? prevCounts[habit] + 1
          : Math.max(0, prevCounts[habit] - 1),
    }));
      return { ...prevStatuses, [key]: newStatus };
    });
    // console.log(habitStatuses);
  };

  return (
    <div className="habit-tracker-week-view">
      <div className="months">
        <div className="previous-month" onClick={handlePreviousWeek}>
          <img
            width="24"
            height="24"
            src="https://img.icons8.com/material-outlined/24/back--v1.png"
            alt="back--v1"
          />
        </div>
        <div className="month">{getMonthYear()}</div>
        <div className="next-month" onClick={handleNextWeek}>
          <img
            width="24"
            height="24"
            src="https://img.icons8.com/material-outlined/24/forward.png"
            alt="forward"
          />
        </div>
      </div>
      <div className="day-of-the-week">
        {weekdays.map((day) => (
          <label>{day}</label>
        ))}
      </div>
      {/* <h1>Habit Tracker</h1> */}
      <div className="habits">
        {habitList.map((habit) => (
          <>
            <div className="habit-info">
              <div className="habit-name">{habit}</div>
              <div className="habit-time">time</div>
            </div>
            <div className="habit-dates">
              {dates.map((date) => (
                <div
                  className={`habit-date ${
                    habitStatuses[`${date}-${habit}`] === "done"
                      ? "done"
                      : `${
                          habitStatuses[`${date}-${habit}`] === "not done"
                            ? "not-done"
                            : ""
                        }`
                  }`}
                  onClick={() => handleTodaysStatus(date, habit)}
                >
                  {date}
                </div>
              ))}
            </div>
          </>
        ))}
      </div>
    </div>
  );
}
export default HabitTrackerWeekView;

我判断了redux-dev-Tool,流程很好,正在更新正确的状态

推荐答案

呼叫store.getState()并不是向存储订阅Reaction组件,而是一次性操作.使用useSelector挂钩订阅store 中的更改.当所选值更改时,组件被触发以重新呈现并 Select 更新的状态值.

例如:

...
import { useDispatch, useSelector } from 'react-redux';
...

function App() {
  const dispatch = useDispatch();

  const habitList = useSelector(state => state.habitList);
  const switchCom = useSelector(state => state.switchCom);
  const currentMonth = useSelector(state => state.currentMonth);
  const doneCount = useSelector(state => state.doneCount);

  const [newHabit, setNewHabit] = useState("");
  
  useEffect(() => {
    console.log("app.js done count ", doneCount);
  }, [doneCount]);


  return (
    <div className="App">
      <NavBar />
      <HabitTrackerWeekView
        habits={habitList}
        dispatch={dispatch}
        currentMonth={currentMonth}
      />
    </div>
  );
}

一百零二

function HabitTrackerWeekView() {
  const dispatch = useDispatch();

  const habitList = useSelector(state => state.habitList);
  const currentMonth = useSelector(state => state.currentMonth);
  const doneCount = useSelector(state => state.doneCount);

  ...

Reactjs相关问答推荐

安装后未渲染tailwind

在Reaction常量函数中未更新状态变量

使用`Link`包装`tr`标记会在Next.js中产生水合错误14

梅X折线图无响应

需要特定的数学函数来标准化动画持续时间

React useEffect 依赖项

Redux 工具包不更新状态

useMemo 依赖项的行为

如何渲染子路径并触发react 路由父加载器?

React:如何使用条件渲染和react 挂钩来更新另一个组件的状态?

MUI TextField Select 菜单的最大高度

使用dayjs时如何在输入类型日期时间本地字段中设置默认值?

加密 Django Rest Framework API 响应 + 解密响应应用程序中的响应

如何在 React 中的 Material Ui 多选中设置默认值?

如何根据数据库中的值设置单选按钮选中? - react

多次响应获取发送请求

你如何使用 refs 访问 React 中映射子项的值?

React LinkProps 的含义

ClearInterval 在 React 中的 useRef 没有按预期工作

添加禁用的默认选项以 Select