【问题标题】:React Child component does not rerender on prop changeReact Child 组件不会在道具更改时重新渲染
【发布时间】:2021-12-04 07:25:43
【问题描述】:

我有一个父组件

// generate an array of objects, which gets passed the the CalendarDateGrid Component
const calculatedCalendarData = (startDate, endDate) => {
  return [
    { calcNormalOrderElectoralBoard: calcNormalOrderElectoralBoard(endDate) },
    { calcNormalDiploma: calcNormalDiploma(startDate) },
  ];
};

export default function Home() {
  const [startDate, setStartDate] = useState(new Date());
  const [endDate, setEndDate] = useState(new Date());
  const [selectedRegion, setSelectedRegion] = useState(
    questions[2].selections[0]
  );
  const [electoralProcess, setElectoralProcess] = useState(
    questions[3].selections[0]
  );
  const [loading, setLoading] = useState(false);
  const [calendarData, setCalendarData] = useState(calculatedCalendarData(startDate, endDate));

  return (
    <div>
      <main className="font-heebo">
        <div className="max-w-full mx-auto">
          <Calendar
            startDate={startDate}
            onDateChange={setStartDate}
            endDate={endDate}
            onEndDateChange={setEndDate}
            selectedRegion={selectedRegion}
            setSelectedRegion={setSelectedRegion}
            electoralProcess={electoralProcess}
            setElectoralProcess={setElectoralProcess}
            calendarData={calendarData}
            setCalendarData={setCalendarData}
            setLoading={setLoading}
          />
        </div>
        <div className="max-w-full mx-auto">
          <CalendarDateGrid
            data={calendarData}
            setData={calculatedCalendarData}
            isLoading={loading}
          />
        </div>
      </main>
    </div>
  );
}

在我的日历组件(它是一个表单)中,我正在保存数据并将该数据传递给我的父级

<div className="py-14">
  <div
    onClick={() => setCalendarData}
    className="cursor-pointer bg-white w-72 mx-auto text-center text-wahl-red rounded"
  >
    <span className="inline-block border-wahl-red rotate-180 border w-5 align-middle" />
    <span type="button" className="inline-block px-3 py-2 text-lg">
      calculate date
    </span>
  </div>
</div>

之后,我尝试将该数据传递给我的 CalendarDateGrid 组件。 基本上应该获取数据并通过该数据生成布局映射:

export default function CalendarDateGrid({ data, isLoading }) {
  const [calendarData, setCalendarData] = useState(data);

  useEffect(() => {
    setCalendarData(data);
  }, [data]);

  return (
    <div className="w-4/5 2xl:w-2/3 mx-auto pb-20">
      {isLoading && (
        <ul
          role="list"
          className="mt-3 grid grid-cols-1 gap-5 sm:gap-12 md:grid-cols-2 xl:grid-cols-3"
        >
          {calendarData.map((calendarItem) => (
...

问题是,如果数据更新,我的子组件不会更新。我正在尝试使用 useEffect 进行更新,但这不起作用。

【问题讨论】:

  • 您传递给子组件的calenderData 的类型是什么?它是对象还是数组?此外,如果您可以提供一个沙盒,这将有助于更快地回答您的问题。
  • 它是一个对象数组
  • calculateCalender 是如何变化的? setCalculateCalender(newArray) ?
  • “calculateCalendar”是状态变量吗?如果不是,则不会重新渲染父级,因此,不会更新任何道具以供子级更新。如果是这种情况,请告诉我,我可以将其设置为答案。
  • 我会改写我的问题

标签: javascript reactjs components


【解决方案1】:

useEffect 挂钩对作为依赖项传递的值进行浅比较。所以如果你想传递一个对象或数组作为你的依赖,你应该定义它到底是什么。

  • 对象依赖

例如,如果你有一个对象作为你的状态,你应该定义哪个属性被认为是一个依赖:

const [user, setUser] = useState({
  name: '',
  age: ''
})

// If you want to run the useEffect on every changes of user
useEffect(() => {
  console.log("a property in object is changing")
}, [...user])

// If you want to run the useEffect only on change of user's age
useEffect(() => {
  console.log("user's age is changing")
}, [user.age])
  • 数组依赖
const [data, setData] = useState([])

// If event that cause change in data, affect on its length
useEffect(() => {
  console.log("array's length is changing")
}, [data.length])

如果data的长度没有改变,或者data是一个内部字段可能改变的对象数组,你可以使用以下方式之一:

  1. 使用JSON.stringify(data)data 值与其先前的值进行比较
const [data, setData] = useState([])

useEffect(() => {
  console.log("array is changing")
}, [JSON.stringify(data)])
  1. 您可以使用use-deep-compare-effect 包,或者如果您确切地知道data 数组的嵌套对象内部的属性是什么,则可以编写自己的自定义钩子。

【讨论】:

  • 感谢您的回答,我用我的组件(几乎所有)的所有信息更新了我的问题,如果您愿意,可以查看它
猜你喜欢
  • 2021-09-01
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-24
  • 1970-01-01
  • 2023-02-15
  • 1970-01-01
相关资源
最近更新 更多