React案例选项卡

116 阅读2分钟

我正在参加「掘金·启航计划」

一、选项卡案例

1.1 新建样式文件

css文件夹下创建tab.css,写入样式:

ul {
    list-style: none;
    display: flex;
    position: fixed;
    bottom: 0;
    left: 0;
    height: 50px;
    line-height: 50px;
    width: 100%;
    margin: 0;
    padding: 0;
    background-color: #fff;
}
ul li {
    flex: 1;
    text-align: center;
    cursor: pointer;
}
.active {
    color: red;
}
dl {
    height: 50px;
    border-bottom: 1px solid gray;
    margin: 70px 0;
}
dl dt {
    font-size: 20px;
}
dl dd {
    font-size: 12px;
    color: gray;
}
input {
    width: 100%;
    height: 50px;
    line-height: 50px;
    font-size: 25px;
    position: fixed;
    top: 0;
    left: 0;
}

1.2 新建独立3个组件

components\moviecomponents下创建3个组件: 在这里插入图片描述

1.3 主逻辑组件

创建tab.js写入:

import React, { Component } from 'react'
import '../css/tab.css'
import Film from './moviecomponents/Film'
import Cinema from './moviecomponents/Cinema'
import Profile from './moviecomponents/Profile'

export default class Tab extends Component {
    state = {
        list: [
            {
                id: 1,
                name: '电影'
            },
            {
                id: 2,
                name: '影院'
            },
            {
                id: 3,
                name: '我的'
            }
        ],
        lIndex: 0
    }
  which() {
      switch (this.state.lIndex) {
          case 0:
              return <Film></Film>
          case 1:
              return <Cinema></Cinema>
          case 2:
              return <Profile></Profile>
          default:
              return null
      }
  }
    
  render() {
    return (
      <div>
          {/* {
              this.state.lIndex === 0 && <Film></Film>
          }
          {
              this.state.lIndex === 1 && <Cinema></Cinema>
          }
          {
              this.state.lIndex === 2 && <Profile></Profile>
          } */}
          {
              this.which()
          }
          
          <ul>
              {
                this.state.list.map((item, index) => 
                    <li onClick={() => {
                        this.indexHandle(index)
                    }} className={this.state.lIndex === index ? 'active' : ''} key={item.id}>{item.name}</li>
                )
              }
          </ul>
      </div>
    )
  }

  indexHandle(index) {
      this.setState({
          lIndex: index
      })
  }
}

由于在setStaterender函数都会执行一边,所以switch 函数也会执行一边。 效果: 在这里插入图片描述 在这里插入图片描述


二、影院组件逻辑

安装axios请求库:npm i axios 在这里插入图片描述

2.1 主逻辑

Cinema.js中写入:

import React, { Component } from 'react'
import axios from 'axios'

export default class Cinema extends Component {

  constructor() {
    super()
    this.state = {
        cinemaList: [],
        backcinemaList: [], // 备份数据,为了防止原数组过滤后赋值 变的越来越少问题(后期接触受控,将重新优化)
    }
    // axios 请求数据
    // axios.get('https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3085018').then((res) => {
    //     console.log(res)
    // }).catch((err) => {
    //     console.log(err)
    // })
    axios({
        url: 'https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3085018',
        method: 'get',
        headers: {
            'X-Client-Info':' {"a":"3000","ch":"1002","v":"5.2.0","e":"1646314068530784943341569"}',
            'X-Host': 'mall.film-ticket.cinema.list'
        }
    }).then((res) => {
        console.log(res.data)
        this.setState({
            cinemaList: res.data.data.cinemas,
            backcinemaList: res.data.data.cinemas
        })
    }).catch((err) => {
        console.log(err)
    })
  }  

  // 后面在生命周期函数 更适合发生ajax请求
  render() {

    return (
      <div>
            <input onInput={this.inputHandle}></input>
            {
                this.state.cinemaList.map((item) => 
                <dl key={item.cinemaId}>
                    <dt>{item.name}</dt>
                    <dd>{item.address}</dd>
                </dl>
                )
            }
      </div>
    )
  }

  inputHandle = (event) => {
    // console.log(event.target.value);
    var newList = this.state.backcinemaList.filter(item => item.name.toUpperCase().includes(event.target.value.toUpperCase()) || 
    item.address.toUpperCase().includes(event.target.value.toUpperCase())) // filter会把过滤完的数据给返回回来
    
    // console.log(newList)
    this.setState({
        cinemaList: newList
    })
  }
}

效果:

在这里插入图片描述 在这里插入图片描述


2.2 setState同步异步问题

新建一个组件asyncstate.js写入:

import React, { Component } from 'react'

export default class Asyncstate extends Component {
  state = {
      count: 1
  }
  render() {
    return (
      <div>
          {this.state.count}
          <button onClick={this.addHandle1}>add1</button>
          <button onClick={this.addHandle2}>add2</button>
      </div>
    )
  }

  addHandle1 = () => {
    this.setState({
        count: this.state.count + 1
    })
    console.log(this.state.count)
    this.setState({
        count: this.state.count + 1
    })
    console.log(this.state.count)
    this.setState({
        count: this.state.count + 1
    })
    console.log(this.state.count)
  }

  addHandle2 = () => {
    setTimeout(() => {
        this.setState({
            count: this.state.count + 1
        })
        console.log(this.state.count)
        this.setState({
            count: this.state.count + 1
        })
        console.log(this.state.count)
        this.setState({
            count: this.state.count + 1
        })
        console.log(this.state.count)
    }, 0)
  }
}

点击add1效果: 在这里插入图片描述 点击 add2效果: 在这里插入图片描述

setState处在同步的逻辑中,异步更新状态,更新真实dom。 setState处在异步的逻辑中,同步更新状态,同步更新真是dom。 setState接受第二个参数,第二个参数是回调函数,状态和dom更新完后就会被触发。

在学习React的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。