首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用React创建交互式SVG组件

使用React创建交互式SVG组件
EN

Stack Overflow用户
提问于 2015-12-26 05:25:22
回答 1查看 8.9K关注 0票数 12

假设我有一个SVG元素,其中包含所有美国州的路径。

代码语言:javascript
运行
AI代码解释
复制
<svg>
    <g id="nh">
        <title>New Hampshire</title>
        <path d="m 880.79902,142.42476 0.869,-1.0765 1.09022,..." id="NH" class="state nh" />
    </g>
    ...
</svg>

SVG数据保存在一个具有.svg扩展名的单独文件中。假设我想要创建映射的React组件,并对其进行完全控制,这样我就可以基于某些外部输入修改单个状态的样式。

使用Webpack,据我所知,我有两个加载SVG标记的选项:使用生料装载机将其作为原始标记插入,并使用dangerouslySetInnerHTML创建一个组件。

代码语言:javascript
运行
AI代码解释
复制
var InlineSvg = React.createClass({
  render() {
    var svg = require('./' + this.props.name + '.svg');
    return <div dangerouslySetInnerHTML={{__html: svg}}></div>;
  }
});

或者手动将标记转换为有效的JSX:

代码语言:javascript
运行
AI代码解释
复制
var NewComponent = React.createClass({
  render: function() {
    return (
        <svg>
            <g id="nh">
                <title>New Hampshire</title>
                <path d="m 880.79902,142.42476 0.869,-1.0765 1.09022,..." id="NH" className="state nh" />
            </g>
            ...
        </svg>
    );
});

最后,假设除了SVG映射之外,还有一个简单的HTML列表显示所有状态。每当用户悬停在列表项上时,对应的SVG路径应移动填充颜色。

现在,我似乎无法理解的是如何更新React组件以反映悬停状态。当然,我可以深入到DOM中,按类名选择SVG状态并更改其颜色,但这似乎并不是这样做的“反应”方式。指手画脚会很感激的。

PS。我使用Redux来处理组件之间的所有通信。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-27 03:29:02

你需要做两件事:

1)在每个列表项上设置一个事件侦听器,以便将突出显示的项通知应用程序。

代码语言:javascript
运行
AI代码解释
复制
<li
    onMouseOver={() => this.handleHover('NH')}
    onMouseOut={() => this.handleUnhover()}
>
    New Hampshire
</li>

2)捕获数据,并将其传播给SVG组件。

这是更复杂的部分,这取决于你如何组织你的应用程序。

  • 如果整个应用程序是一个单独的反应性组件,那么handleHover将简单地更新组件状态。
  • 如果您的应用程序被划分为多个组件,那么handleHover将触发作为支柱传入的回调。

让我们假设后者。组件方法可能如下所示:

代码语言:javascript
运行
AI代码解释
复制
handleHover(territory) {
    this.props.onHighlight(territory);
}

handleUnhover() {
    this.props.onHighlight(null);
}

假设您有一个包含SVG映射和列表的父组件,它可能如下所示:

代码语言:javascript
运行
AI代码解释
复制
class MapWrapper extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            highlighted: null;
        };
    }

    setHighlight(territory) {
        this.setState({
            highlighted: territory
        });
    }

    render() {
        const highlighted = { this.state };
        return (
            <div>
                <MapDiagram highlighted={highlighted} />
                <TerritoryList onHighlight={(terr) => this.setHighlight(terr)} />
            </div>
        );
    }

}

这里的关键是highlighted状态变量。每次发生新的悬停事件时,highlighted的值都会发生变化。此更改将触发重呈现,新值将传递给MapDiagram,后者可以确定要突出显示的SVG的哪一部分。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34471758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档