Реагировать на причину отрисовки - PullRequest
1 голос
/ 21 февраля 2020

Я играю с простыми компонентами React, чтобы понять, когда происходит рендеринг.

Пример 1 - Первоначально визуализируется один раз. Независимо от количества нажатий кнопки она не отображается. Это ожидается.

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [state, setState] = useState([
    { id: 1, name: "test1" },
    { id: 2, name: "test2" }
  ]);
  const onClick = () => setState(data => data);
  console.log("App rendered");
  return (
    <div className="App">
      <h1>Test if setting same data causes re-rendering</h1>
      <button onClick={onClick}>Call setState with same data</button>
      {state.map(({ id, name }) => (
        <p key={id}>{name}</p>
      ))}
    </div>
  );
}

Образец 2 - Первоначально визуализируется дважды, поскольку useEffect обновляет setMessages со значением. Это ожидается. Однако, если кнопка нажимается 1+ раз, она рендерится один раз. Он даже не должен перерисовываться, поскольку устанавливается то же значение. Почему это рендеринг, если не обновляется новое значение / ссылка?

import React, { useState, useEffect, useMemo, useCallback } from "react";
import axios from "axios";
import "./styles.css";

const days = [
  "Sunday",
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday"
];
export default function App() {
  const [messages, setMessages] = useState([]);
  useEffect(() => {
    axios
      .get(`https://api.myjson.com/bins/10xva4`)
      .then(({ data: { messages } }) => setMessages(messages));
  }, []);
  const Display = useMemo(
    () =>
      messages.map(({ content, senderUuid, sentAt }, index) => {
        let d = new Date(sentAt);
        return (
          <div className="container" key={index}>
            <p>Content: {content}</p>
            <p>SenderUuid: {senderUuid}</p>
            <p>DayOfTheWeek: {d.getDate()}</p>
            <p>Month: {d.getMonth()}</p>
            <p>Day: {days[d.getDay()]}</p>
            <p>Year: {d.getFullYear()}</p>
          </div>
        );
      }),
    [messages]
  );
  const onClick = useCallback(() => setMessages(messages => messages), []);
  console.log("App rendered");
  // console.log({ messages });
  return useMemo(
    () => (
      <div className="App">
        <button onClick={onClick}>Call setMessages with same data</button>
        {Display}
      </div>
    ),
    [Display, onClick]
  );
}

ОБНОВЛЕНИЕ: Подтверждено, что ошибка реагирует. - https://github.com/facebook/react/issues/18098

...