Как остановить рендеринг A и B в React? - PullRequest
1 голос
/ 22 февраля 2020

enter image description here

import React, { useState, useEffect, useCallback } from "react";

export const Root = () => {
  const [items, setItems] = useState(["A", "B"]);

  const _onClick = useCallback( item => {
    return () =>alert(item);
  },[]);
  return (
    <>
      <button onClick={() => setItems(["A", "B", "C"])}>Button</button>
      {items.map((item, index) => (
        <Item key={index} item={item} onClick={_onClick(item)} />
      ))}
    </>
  );
};

const Item = React.memo(({ item, onClick }) => {
  useEffect(() => {
    console.log("Item: ", item);
  });
  return <button onClick={onClick}>{item}</button>;
});

Как нам остановить повторный рендеринг A и B? В результате я хочу, чтобы при нажатии кнопки была записка на консоли и «Item: C».

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

Поскольку onClick из <Item/> является новым при каждом рендеринге, это приведет к повторному рендерингу A и B.

Вы можете использовать React.memo второй параметр для проверки, например:

const Item = React.memo(({ item, onClick }) => {
    // ...
    return <button onClick={onClick}>{item}</button>;
}, (prevProps, nextProps) => {
    console.log(Object.is(prevProps.onClick, nextProps.onClick)); // console: false
});

Подробнее см. do c.


В вашем коде _onClick(item) будет возвращать новый обратный вызов при каждом рендере.

<Item key={index} item={item} onClick={_onClick(item)} />

Вы можете изменить _onClick на следующее:

const _onClick = useCallback(item => alert(item), []);

Далее, передать _onClick для Item и изменить способ выполнения кнопки onClick.

<Item key={index} item={item} onClick={_onClick} />

//...

<button onClick={() => onClick(item)}>{item}</button>

Полный код выглядит следующим образом:

import React, { useCallback, useState } from 'react';

export const Root = () => {
    const [items, setItems] = useState(['A', 'B']);

    const _onClick = useCallback(item => alert(item), []);
    return (
        <>
            <button onClick={() => setItems(['A', 'B', 'C'])}>Button</button>
            {items.map((item, index) => (
                <Item key={index} item={item} onClick={_onClick} />
            ))}
        </>
    );
};

const Item = React.memo(({ item, onClick }) => {
    useEffect(() => {
        console.log("Item: ", item);
    });
    return <button onClick={() => onClick(item)}>{item}</button>;
});

0 голосов
/ 22 февраля 2020

Вы звонили _onClick не с того места. Вместо вызова компонента Item следует вызвать событие onClick кнопки.

Проверить эти рабочие Кодовая песочница .

...