每次鼠标悬停时重新绘制自定义标签渲染

如何解决每次鼠标悬停时重新绘制自定义标签渲染

我为饼图创建自定义标签

CustomLabel.js

const renderCustomizedLabel = (props,centerText) => {
    console.log("rendered")
    return (
        <g>...</g>
    );
};

export default renderCustomizedLabel;

CustomPieChart.js

export default class Example extends PureComponent {
    constructor(props){
        super(props);
    }
    render() {
        return (
            <ResponsiveContainer width="100%" aspect={2}>
                <PieChart width={600} height={600}>
                    <Pie  
                     data={this.props.data} 
                     dataKey="value" 
                     nameKey="name" 
                     cx="50%" cy="50%" innerRadius={80} outerRadius={90}
                     label={(a)=>CustomPieChartLabel(a,this.props.centerText)}>
                     {this.props.data.map((entry,index) => (<Cell key={`cell-${index}`} fill={entry.color} />))}
                     </Pie>
                </PieChart>
             </ResponsiveContainer> 
        );
    }
}

问题

每次将鼠标悬停在单元格上时,renderCustomizedLabel 都会工作并为每个数据渲染。

在上面的代码中,我没有使用任何 onMouseMove、onMouSEOver、onMouseEnter 方法

enter image description here

如上图所示,当鼠标悬停在红色、蓝色或灰色区域时,console.log("rendered") 工作 3 次。

为了解决这个问题,我尝试使用 React.memo

CustomLabelWithMemo.js

const MemoComponent = React.memo(function renderCustomizedLabel(props) {
    console.log("rendered")
    return (
        <g>...</g>
    );
});

export default MemoComponent

但它给了我一个错误

TypeError: Object(...) 不是函数

我该如何解决这个问题?

转载链接 CodeSandBox

解决方法

我认为查看沙箱的主要问题是,在将 MemoComponent 传递给 label Pie 组件。

你这样做:

label={(a) => CustomPieChartLabel(a,this.props.centerText)}

相反,您可以这样做:

label={<CustomPieChartLabel centerText={this.props.centerText} />}

我还稍微调整了您的 CustomPieChartLabel.js 文件:

import React from "react";

const RADIAN = Math.PI / 180;

const renderCustomizedLabel = (props) => {
  console.log("rendered");
  const {
    cx,cy,midAngle,outerRadius,fill,payload,percent,value,centerText
  } = props;
  const sin = Math.sin(-RADIAN * midAngle);
  const cos = Math.cos(-RADIAN * midAngle);
  const sx = cx + (outerRadius + 10) * cos;
  const sy = cy + (outerRadius + 10) * sin;
  const mx = cx + (outerRadius + 30) * cos;
  const my = cy + (outerRadius + 30) * sin;
  const ex = mx + (cos >= 0 ? 1 : -1) * 30;
  const ey = my;
  const textAnchor = cos >= 0 ? "start" : "end";
  return (
    <g>
      <text x={cx} y={cy} textAnchor="middle" fill={fill}>
        {centerText.title}
      </text>
      <text x={cx} y={cy} dy={20} textAnchor="middle" fill={fill}>
        {centerText.value}
      </text>

      <path
        d={`M${sx},${sy}L${mx},${my}L${ex},${ey}`}
        stroke={fill}
        fill="none"
      />
      <circle cx={ex} cy={ey} r={2} fill={fill} stroke="none" />
      <text
        style={{ fontWeight: "bold" }}
        x={ex + (cos >= 0 ? 1 : -1) * 12}
        y={ey}
        textAnchor={textAnchor}
        fill={fill}
      >
        {payload.name}
      </text>
      <text
        x={ex + (cos >= 0 ? 1 : -1) * 12}
        y={ey}
        dy={18}
        textAnchor={textAnchor}
        fill="#999"
      >
        {value}
      </text>
    </g>
  );
};

const CustomPieChartLabel = React.memo(renderCustomizedLabel);

export default CustomPieChartLabel;

Sandbox example

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?