0

我使用 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)

当我在选择组件中更改值时,areEqual 似乎不起作用,上传组件中所有图像的地址将重新加载。为什么...?

像这样的表现:

在此处输入图像描述

我能怎么做?

4

3 回答 3

2

重新渲染可能是由于内部状态更改(setValue(value))。React.memo不会阻止由状态更改引起的重新渲染。

React.memo 仅检查 prop 更改。如果你封装在 React.memo 中的函数组件在其实现中有一个 useState 或 useContext Hook,它仍然会在状态或上下文发生变化时重新渲染。

文档

于 2020-07-21T08:47:22.183 回答
0

非常感谢~我发现我在 Uploader 中的值的类型是数组,所以当 Select change 时,props.onChange会导致值改变,所以 Uploader 会重新加载。

我像这样在上传器组件中添加 useEffect : useEffect(() => { setValue(formatValue(props.value)) }, [JSON.stringify(props.value)]),然后图像不会重新加载...

于 2020-07-21T11:38:40.700 回答
0

您将onChange参数传递给Uploader喜欢onChange={(val) => handleChange(val)},因此这有效地在每个渲染上创建了新函数,并且可能React.memo因此而给出误报。如果它每次都是不同的 Array 实例,Uploader那么你也有props.onChange(fileList)可能fileList也是原因。

除了@Ramesh Reddy的回答之外,您还调用setValue了 Select 更改,这也可能是原因,因为您使用新值作为 prop to Uploader

如果这不是原因,您可以添加带有重现问题的代码框示例。

于 2020-07-21T09:51:59.703 回答