使用Ajax 获取热门搜索 推荐数据

本文介绍如何在React应用中实现“换一批”热门搜索功能,通过使用mock数据和mock.js来模拟AJAX请求,同时展示了如何组织和展示搜索建议,并通过React的状态管理来控制显示与隐藏。

前面,我们写好了热门搜索的样式解构。下面,我们来做里面“换一批”的功能。换一批数据,通过 ajax 方式获取。

这里,我们是mock 数据。要借助一下mock.js。

先现在mock.js 到项目: yarn add mockjs

安装好后,我们在src 下面新建一个文件mockdata.js 文件,然后在这个文件里写下面的内容。

 

然后我们打开 src/common/header 下的index.js 文件,如下。

import React from 'react';
import {connect} from 'react-redux';
import {
  HeaderWrapper,
  Logo,
  Nav,
  NavItem,
  NavSearch,
  Addition,
  Button,
  SearchWrapper,
  SearchInfo,
  SearchInfoTitle,
  SearchInfoSwitch,
  SearchInfoItem
} from './style';
import '../../statics/iconfont/iconfont.css';
import { CSSTransition } from 'react-transition-group';
import { actionCreators } from './store';

const getListArea = (show) => {
  if (show) {
    return (
      <SearchInfo>
            <SearchInfoTitle>
              热门搜索
              <SearchInfoSwitch>换一批</SearchInfoSwitch>
            </SearchInfoTitle>
            <div>
              <SearchInfoItem>教育</SearchInfoItem>
              <SearchInfoItem>植物</SearchInfoItem>
              <SearchInfoItem>食物</SearchInfoItem>
              <SearchInfoItem>花朵</SearchInfoItem>
              <SearchInfoItem>水</SearchInfoItem>
              <SearchInfoItem>江河</SearchInfoItem>
              <SearchInfoItem>天空</SearchInfoItem>
              <SearchInfoItem>尘埃</SearchInfoItem>
            </div>
          </SearchInfo>
    )
  } else {
    return null;
  }
};

const Header = (props) => {
  return (
    <HeaderWrapper>
      <Logo href='/'/>
      <Nav>
        <NavItem className='left active'>首页</NavItem>
        <NavItem className='left'>下载</NavItem>
        <NavItem className='right'>登录</NavItem>
        <NavItem className='right'>
          <span className="iconfont">&#xe636;</span>
        </NavItem>
        <SearchWrapper>
          <CSSTransition
            in={props.focused}
            timeout={200}
            classNames="slide"
          >
            <NavSearch
              placeholder="搜索"
              className={props.focused ? "focused" : ""}
              onFocus={props.handleFocus}
              onBlur={props.handleBlur}
            ></NavSearch>
          </CSSTransition>
          <span
            className={props.focused ? "focused iconfont" : "iconfont"}
          >&#xe623;</span>
          {getListArea(props.focused)}
        </SearchWrapper>
      </Nav>
      <Addition>
      <Button className='writting'>
        <span className="iconfont">&#xe63a;</span>
        写文章
      </Button>
        <Button className='reg'>注册</Button>
      </Addition>
    </HeaderWrapper>
  )
}

const mapStateToProps = (state) => {
  return {
    focused: state.get("header").get("focused")
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    handleFocus () {
      dispatch(actionCreators.searchFocus());
    },
    handleBlur () {
      dispatch(actionCreators.searchBlur());
    }

  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Header);

这个Header 是一个无状态组件,我们要继续扩展他。这样它可能就会函数里嵌套函数,而且代码量会很多,这样子就会很难维护。所以,我们先把Header 改回为一个正常的组件。如下。

import React, { Component } from 'react';
import {connect} from 'react-redux';
import {
  HeaderWrapper,
  Logo,
  Nav,
  NavItem,
  NavSearch,
  Addition,
  Button,
  SearchWrapper,
  SearchInfo,
  SearchInfoTitle,
  SearchInfoSwitch,
  SearchInfoItem
} from './style';
import '../../statics/iconfont/iconfont.css';
import { CSSTransition } from 'react-transition-group';
import { actionCreators } from './store';

class Header extends Component {
  render() {
    let { focused, handleFocus, handleBlur } = this.props;
    return (
      <HeaderWrapper>
        <Logo href='/'/>
        <Nav>
          <NavItem className='left active'>首页</NavItem>
          <NavItem className='left'>下载</NavItem>
          <NavItem className='right'>登录</NavItem>
          <NavItem className='right'>
            <span className="iconfont">&#xe636;</span>
          </NavItem>
          <SearchWrapper>
            <CSSTransition
              in={focused}
              timeout={200}
              classNames="slide"
            >
              <NavSearch
                placeholder="搜索"
                className={focused ? "focused" : ""}
                onFocus={handleFocus}
                onBlur={handleBlur}
              ></NavSearch>
            </CSSTransition>
            <span
              className={focused ? "focused iconfont" : "iconfont"}
            >&#xe623;</span>
            {this.getListArea(focused)}
          </SearchWrapper>
        </Nav>
        <Addition>
        <Button className='writting'>
          <span className="iconfont">&#xe63a;</span>
          写文章
        </Button>
          <Button className='reg'>注册</Button>
        </Addition>
      </HeaderWrapper>
    )
  }

  getListArea = (show) => {
    if (show) {
      return (
        <SearchInfo>
              <SearchInfoTitle>
                热门搜索
                <SearchInfoSwitch>换一批</SearchInfoSwitch>
              </SearchInfoTitle>
              <div>
                <SearchInfoItem>教育</SearchInfoItem>
                <SearchInfoItem>植物</SearchInfoItem>
                <SearchInfoItem>食物</SearchInfoItem>
                <SearchInfoItem>花朵</SearchInfoItem>
                <SearchInfoItem>水</SearchInfoItem>
                <SearchInfoItem>江河</SearchInfoItem>
                <SearchInfoItem>天空</SearchInfoItem>
                <SearchInfoItem>尘埃</SearchInfoItem>
              </div>
            </SearchInfo>
      )
    } else {
      return null;
    }
  };

}

const mapStateToProps = (state) => {
  return {
    focused: state.get("header").get("focused")
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    handleFocus () {
      dispatch(actionCreators.searchFocus());
    },
    handleBlur () {
      dispatch(actionCreators.searchBlur());
    }

  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Header);

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值