总感觉做技术的 不做些总结是对自己的不负责任 所以 从今天开始 这是我的第一篇博客,希望这是一个好的开始,坚持住。
接下来 我就来介绍一个 我最近在学习 react 中做的一个小例子。
我用react 做了一个搜索关键字的小例子 通过ref 属性获取到 用户手动在input输入框中输入的内容 通过 ajax 向后台发送请求,后台通过从前台拿到的数据进行模糊查询,在把含有关键字的字符串返回给前台,用户可以通过鼠标进行选择,也可以通过键盘上下键进行选择,上下移动时通过给通过给当前this.index的li 添加 .active 类,以达到选中行高亮显示的效果。
学习中遇到的困难:
1.根据请求回来的数据(一个数组)的个数,循环生成li,利用data.map(function(row){});函数。
具体代码:
genRows(data){
if(data == "")
return "";
var that = this;
var i=0,j=0;
var rows = data.map(function(row){
i++;
return <li key={i} onClick={that.liClickSelected.bind(that)}>{row}</li>
})
return (
<ul className="selected" style={listStyle}>
{rows}
</ul>
);
}
另外 每个li 都要加个键值 key 这个是初学者经常会碰到的一个错误信息,
waring:Each child in an array or iterator should have a unique "key" prop ..................
遇到这个错误 给li 加一个key 即可。
2.通过键盘 上下键 进行选择
这里完全可以用js,jquery大胆的写,卡住我的地方就在于li边界处理的时候,定义一个全局的index,按向上键 index--,向下键index++,这时候判断index是否是第一个和最后一个 如果是 都直接return ,什么都不做,而 这个判断需要放在 index++ /index-- 的上面,
3.把选中的li的innerText的值取出来 放到 input中,
其实这个问题很简单,但我让我苦恼了半天,第一次遇到这个问题的时候,我不知道react中取两个标签之间的文本应该用什么属性,我还苦苦的网上搜寻,后来我想起来一个非常好用的方法,就是把你的要操作的对象 在 控制台dir 或者直接点开 小三角,你想找什么属性,方法,一个一个点开,每点开一个就是一个 .(点) 每一层的东西你都可以 .(点) 出来,这样问题就迎刃而解了。
果然,react里的文本叫innerText 而不是向jQuery里面的innerhtml
全部都在下面
import React, {
Component,
PropTypes
} from 'react';
import ReactDOM from 'react-dom';
import {SimpleRow, SelectGroup} from '../components/EditableRow'
var listStyle={
paddingLeft:8,
position:"absolute",
minHeight:50,
width:250,
left:34,
top:25,
borderWidth:1,
borderColor:"#ddd",
borderStyle:"solid",
listStyle:"none"
}
class SelectInfo extends React.Component{
constructor(props){
super(props);
this.state={
data:null,
searchInfo:""
}
this.index=0;
}
searchKeyword(e){
this.index=0;
let name = e.target.value;
if(name == ""){
this.setState({
searchInfo : ""
});
return;
}
//console.log(name);
$.ajax({
url:"/selectInfo",
type:"post",
data: JSON.stringify({Information:this.refs.information.value}),
dataType: 'json',
contentType : 'application/json',
success:function(data){
if(data){
this.setState({
searchInfo : data.data
});
}else{
searchInfo:""
}
}.bind(this),
error:function(){
alert("请求失败");
}
});
}
genRows(data){
if(data == "")
return "";
var that = this;
var i=0,j=0;
var rows = data.map(function(row){
i++;
return <li key={i} onClick={that.liClickSelected.bind(that)}>{row}</li>
})
return (
<ul className="selected" style={listStyle}>
{rows}
</ul>
);
}
liClickSelected(e){
//console.log(e.target.innerText);
this.refs.information.value=e.target.innerText;
this.setState({
searchInfo:""
});
}
handleKeyPress(e){
var code = e.keyCode;
var lis=$(".selected>li");
lis.removeClass("active");
var firstLi=$(".selected>li:first-child");
//console.log(firstLi);
var lastLi=$(".selected>li:last-child");
//firstLi.attr("class","selected");
//下
if (code == 40) {
if(this.index==($(".selected>li").length)){
return;
}
$(lis[this.index]).addClass("active");
this.index++;
console.log(this.index);
}
//上
if (code == 38) {
if(this.index==0){
return;
}
this.index--;
$(lis[this.index-1]).addClass("active");
console.log(this.index);
}
if (code == 13) {
this.refs.information.value=$(".selected>li")[this.index-1].innerText;
//console.log($($(".selected>li")[this.index]));
this.setState({
searchInfo:""
});
this.index=0;
}
}
render(){
var rows = this.genRows(this.state.searchInfo);
return(
<div style={{marginLeft:50,position:"relative"}}>
<label>搜索:</label>
<input style={{width:250,paddingLeft:8}} type="text" name="search" ref="information" placeholder="--请输入检索关键字--" onKeyDown={this.handleKeyPress.bind(this)} onChange={this.searchKeyword.bind(this)}/>
{rows}
</div>
);
}
}
ReactDOM.render(
<SelectInfo />,
document.getElementById("selectInfo")
)