Я использую React.memo для управления повторным рендерингом, но мой компонент все еще перерисовывается. мой код такой:

В моем компоненте шаблона:

const Template = (props: Props) => {
  const { propsValue, data } = props
  const [value, setValue] = useState(propsValue)

  const handleChange = (value) => {
    setValue(value)
    props.onChange(value)
  }
  
  return (
    <div>
      {info.type === 'input' && <Input value={value} onChange={(event, val) => handleChange(val) onBlur={(event) => handleBlur()} />
      {info.type === 'image' && <Uploader multiple value={value} uploadUrl={data.uploadUrl} onChange={(val) => handleChange(val)} />
      {info.type === 'select' && <Select onChange={(val) => handleChange(val)} />
    </div>
  )
}

const areEqual = (prevProps, nextProps) => {
  if (JSON.stringify(prevProps) !== JSON.stringify(nextProps)) {
    return false
  }
  return true
}

export default React.memo(EditTemplate, areEqual)

В моем компоненте загрузки:

const Uploader = props => {
  const [value, setValue] = useState(props.value)
  let { uploadUrl, multiple } = props

  const handleChange = ({ file, fileList }) => {
    if (file.status === 'done') {
      setValue(fileList)
      props.onChange(fileList)
    } else {
      setValue(fileList)
    }
  }

  return (
     <div>
       <Upload fileList={value} multiple={multiple} action={uploadUrl} onChange={handleChange} />
     </div>
  )
}

const areEqual = (prevProps, nextProps) => {
  if (JSON.stringify(prevProps) !== JSON.stringify(nextProps)) {
    return false
  }
  return true
}

export default React.memo(Uploader, areEqual)

Когда я изменяю значение в Select Component, areEqual кажется не работает, адрес всех изображений в Upload Component будет перезагружен. Зачем...?

Производительность как это:

enter image description here

Как я могу сделать?

0
serenas 21 Июл 2020 в 11:38

2 ответа

Большое спасибо ~ Я обнаружил, что тип моего значения в Uploader - это массив, поэтому, когда Select change, props.onChange приведет к изменению значения, поэтому Uploader перезагрузится.

Я добавляю useEffect в Uploader Component следующим образом: useEffect(() => { setValue(formatValue(props.value)) }, [JSON.stringify(props.value)]), и тогда изображения не будут перезагружаться ...

0
serenas 21 Июл 2020 в 11:38

Повторное отображение может быть из-за внутреннего изменения состояния (setValue(value)). React.memo не предотвращает повторное отображение, вызванное изменением состояния.

React.memo только проверяет изменения реквизита. Если ваш компонент функции, обернутый в React.memo, имеет в своей реализации useState или useContext Hook, он все равно будет перерисовываться при изменении состояния или контекста.

Документы

2
Ramesh Reddy 21 Июл 2020 в 08:47