我的第一篇博客 react+express+webpack实现关键字搜索

总感觉做技术的 不做些总结是对自己的不负责任  所以 从今天开始  这是我的第一篇博客,希望这是一个好的开始,坚持住。

接下来 我就来介绍一个 我最近在学习 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")
)


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值