我学习 React,阅读文档,教程。我决定尝试将 JSP 翻译成 React 的一个单独的前端。我从一个小组件开始,这就是自动搜索,原理是,我们输入一个单词,它会给出选项。
几乎一切都解决了,但我不知道如何通过上下键滚动列表,我不知道如何传递上面的属性并告诉一个或另一个 li 将类更改为选中。
我尝试使用 map(item, key),但是如何将属性传递给这个项目,例如?
这是我的代码,我也想请你看看我是否把它清理干净了,或者如果有评论立即解析它们,我将不胜感激:)
import React, { Component } from "react";
import "./App.css";
class ProductRow extends React.Component {
constructor(props) {
super(props);
this.handlerrOnMouseOver = this.handlerrOnMouseOver.bind(this);
this.handlerrOnMouseOut = this.handlerrOnMouseOut.bind(this);
this.handlerrOnMouseDown = this.handlerrOnMouseDown.bind(this);
this.state = {
class: ""
};
}
handlerrOnMouseOver() {
this.setState({
class: "selected"
});
}
handlerrOnMouseOut() {
this.setState({
class: ""
});
}
handlerrOnMouseDown() {
this.props.callback(this.props.product.station);
}
render() {
const product = this.props.product;
return (
<li
className={this.state.class}
onMouseOver={this.handlerrOnMouseOver}
onMouseOut={this.handlerrOnMouseOut}
>
<a href="javascript:void(0);" onMouseDown={this.handlerrOnMouseDown}>
{product.station}
</a>
</li>
);
}
}
class ProductTable extends React.Component {
render() {
const filterText = this.props.filterText;
const rows = [];
if (filterText !== "") {
this.props.products.map((product, key) => {
if (
product.station.toLowerCase().indexOf(filterText.toLowerCase()) ===
-1 ||
rows.length === 20
) {
return;
} else {
rows.push(
<ProductRow
product={product}
key={key}
callback={this.props.callback}
/>
);
}
});
}
var style = {
width: "100%",
fontSize: 14
};
if (rows.length > 0) {
return (
<div className="sf_suggestion">
<ul tabIndex="-1" style={style}>
{rows}
</ul>
</div>
);
} else {
return <div />;
}
}
}
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.handlerFilterTextChange = this.handlerFilterTextChange.bind(this);
this.handlerOnKeyUp = this.handlerOnKeyUp.bind(this);
this.handlerOnBlur = this.handlerOnBlur.bind(this);
this.changeValue = this.changeValue.bind(this);
this.handlerOnFocus = this.handlerOnFocus.bind(this);
this.state = {
visible: true,
filterText: "",
key: ""
};
}
handlerFilterTextChange(e) {
e.preventDefault();
this.setState({ filterText: e.target.value });
}
handlerOnKeyUp() {
var key = window.event.keyCode;
if (key === 38 || key === 40 || key === 13) {
this.setState({ key: key });
}
if (key === 27) {
this.setState({ visible: false });
}
}
changeValue(e) {
this.setState({ filterText: e });
this.handlerOnBlur();
}
handlerOnBlur() {
this.setState({ visible: false });
this.setState({ key: "" });
}
handlerOnFocus() {
if (!this.state.visible) {
this.setState({ visible: true });
}
}
render() {
return (
<p className="inp">
<label>
<input
type="text"
placeholder=" "
value={this.state.filterText}
onChange={this.handlerFilterTextChange}
onFocus={this.handlerOnFocus}
onKeyUp={this.handlerOnKeyUp}
onBlur={this.handlerOnBlur}
/>
<span className="label">{this.props.name}</span>
<span className="border" />
{this.state.visible && (
<ProductTable
products={this.props.products}
filterText={this.state.filterText}
keyUp={this.state.key}
callback={this.changeValue}
/>
)}
</label>
</p>
);
}
}
class App extends Component {
render() {
return (
<table>
<tbody>
<td>
<SearchBar products={this.props.products} name={"Имя"} />
</td>
</tbody>
</table>
);
}
}
export default App;
带有注释的重构版本:
我的版本(我不确定为什么在 JS 中而不是在 CSS 中处理悬停时的颜色变化,但我没有改变它,而是在代码中做到了):