如何在 ReactJS 中突出显示树中的焦点节点?



>假设我们有一个渲染到 DOM 树的树结构,如下所示:

<ul>
<li>Outer
<ul>
<li>Inner
<ul>
<li>Inner Inner</li>
</ul>
</li>
</ul>
</li>
</ul>

我们要突出显示"聚焦"(鼠标悬停(节点,这里的重点是,当突出显示内部节点时,不应突出显示其父节点。

使用 jQuery,您可以访问父节点,解决方案非常简单 http://jsfiddle.net/D7jwq/2/:

$("li").mouseover(function(e) {
$(this).addClass("red").parents().removeClass("red");
e.stopPropagation();
}).mouseout(function(e) {
$(this).removeClass("red");
});

但是如何在ReactJS中获得类似的效果呢?

你根本不需要javascript,它可以(并且必须(用css解决。

li:hover {
background-color: #f00;
}

有关更多详细信息,请参阅 https://www.w3schools.com/cssref/sel_hover.asp。

React 也有鼠标悬停和鼠出事件 https://reactjs.org/docs/events.html

jQuery$("li")将这些事件隐式设置为所有<li>元素。

在 React 中,你必须将这些事件显式设置为你的<li>元素。

为了做到这一点,我为每个节点管理了一个"聚焦"的状态,并在鼠标事件over和触发out时更新此状态。请注意,从父节点移动到子节点时不会触发leave,您可以观察这些事件之间的控制台输出是否不同。

ev.stopPropagation()用于确保只有一个节点同时聚焦

与jQuery方法不同,您不能访问节点的父节点,因此您必须管理每个节点的状态。

App.tsx

import * as React from 'react';
class MouseEventTest extends React.Component {
public render() {
class Echo extends React.Component<{title}, {focused}> {
constructor(props) {
super(props)
this.state = {focused: false}
this.echo = this.echo.bind(this)
}
public echo(title, evName) {
return (ev) => {
ev.preventDefault()
ev.stopPropagation()
console.log(title, evName, ev)
if (['over', 'out'].indexOf(evName) >= 0) {
this.setState({focused: (['enter', 'over'].indexOf(evName) >= 0)})
}
}
}
public render() {
const title = this.props.title
return (
<div style={{display: "block", color: (this.state.focused ? "red" : "inherit"), background: '#3bdb7b50'}}
onClick={this.echo(title, 'click')}
onMouseEnter={this.echo(title, 'enter')}
onMouseOver={this.echo(title, 'over')}
onMouseOut={this.echo(title, 'out')}
onMouseLeave={this.echo(title, 'leave')}
>
{"(" + title + " "}
{this.props.children}
{" " + title + ")"}
</div>
)
}
}
return (
<Echo title="Lv1">
<Echo title="Lv2">
<Echo title="Lv3">
abc
</Echo>
</Echo>
</Echo>
)
}
}
class App extends React.Component {
public render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to React</h1>
</header>
<MouseEventTest />
</div>
);
}
}
export default App;

要执行上面的代码,你可以运行create-react-app my-app --scripts-version=react-scripts-ts来初始化一个目录,并用上面的代码替换src/App.tsx。 也许需要以下配置。

tslint.json

{
"rules": {
"no-console": false,
"max-classes-per-file": false,
"comment-format": false,
"jsdoc-format": false
}
}

tsconfig.json

{
"compilerOptions": {
"noImplicitAny": false,
"noUnusedLocals": false,
}
}

最新更新