从0-1搭建简易电商平台之路


theme: channing-cyan

省流:本文搭建了简易购物车,并将页面数据替换为服务器中数据。

前言:实现react+ts中项目的logo与字体设置

image.png

在项目中通常是使用assets文件夹存储字体样式/logo的部分,在该项目中我使用Slidefu字体(在index.css中全局配置即可,如下)

@font-face {
  font-family: 'Slidefu';
  src: local('Slidefu'), url(./assets/fonts/Slidefu-Regular-2.ttf) format('truetype');
}

全局环境配置成功后在h1中使用该字体样式便可成功显示可爱的字体:

h1{
  font-family: "Slidefu";
  font-size: 72px;
}

image.png

logo设时可以使用npm i react-icons插件选择喜欢的图表样式。

正文:简易购物车

首先得有一个购物车组件对吧,因为涉及到state状态所以我选择类组件。

class ShoppingCart extends React.Component{}

大家都知道在类组件中两个必不可少的左膀右臂:props与state,在本项目中全程使用ts语言约束变量,它们两个也不例外。

interface Props {}
interface State {}

这两个接口便是存储了该类组件的约束变量类型

class ShoppingCart extends React.Component<Props, State> {
  constructor(props: Props) { //约束props和state
    super(props);
    this.state = {};
  }

成功约束完变量类型后可以设置一些细小的state,例如点击span触发事件弹出购物车的item栏,再次点击则消失,此处需要一个state用来保存点击的布尔类型状态。

image.png

再设置点击按钮时更改state状态即可。

又是由于该项目语言为ts,所以少不了每一个约束。当点击按钮后传来的e形参,我们要保证点击的元素是SPAN标签,否则无法展示item栏。此处引申出target与currentTarget两个属性:

  1. target是事件发生的元素本身;

  2. currentTarget是事件处理的元素,也就是触发该事件的button。

为了更好的理解这两个属性,使用如下代码进行测试:

 <button  className={styles.button}
          onClick={this.handleClick}>
          <FiShoppingCart /> //购物车组件
          <span>购物车 2 (件)</span> 
</button>

通过点击两次button按钮测试两者的区别,控制台输出如下:

image.png

所以得出结果,我们需要保证点击的e.target元素标签名为SPAN才会触发state改变,如下:

 handleClick = (e:React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
    if((e.target as HTMLElement).nodeName === "SPAN"){
      this.setState({ isOpen: !this.state.isOpen });
    }
  }

当isOpen的状态为true时item栏的display属性为block,当为false时item栏的display属性为none.实现li栏的显示与隐藏。

image.png

获取网络API数据

将固定的json数据转化为从服务器中获取动态的数据并存放于空数组中。

在类组件钩子函数componentDidMount中使用网络请求

componentDidMount(){
   fetch("https://jsonplaceholder.typicode.com/users")
      .then((res) => res.json())
      .then((data) => { robotGallery:data })
}

之后将数组中的数据显示在页面就好。

换种方式,如果使用钩子函数的话也可以:

定义一个any类型数组以便存放请求回来的数据
 const [robotGallery, setRobotGallery] = useState<any>([])

使用useEffect发送网络请求,注意当第二个参数为空数组时,效果与类组件中componentDIdMount相同,只会在挂在完成后立即执行一次且只执行一次。

useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((res) => res.json())
      .then((data) => { setRobotGallery(data) })
  })

一些疑问be like:

Q:如何在useEffect中使用async await??

A:已知直接使用async await会报错,所以要规避这个问题,使用其他方式。

image.png

解决方式:将async函数封装成另一个函数后再一并调用,就不会报错啦。

 useEffect(()=>{
    const fetchData = async ()=>{
      const res = await fetch("https://jsonplaceholder.typicode.com/users")
      const data = await res.json()
      setRobotGallery(data)
    }
    fetchData()
  },[])

Q:如何处理异常??

A:可直接使用try catch来捕获异常,将error显示在页面某一处方便监听错误。

 const [error, setError] = useState<string>()
 useEffect(()=>{
    const fetchData = async ()=>{
    try{
      const res = await fetch("https://jsonplaceholder.typicode.com/users")
      const data = await res.json()
      setRobotGallery(data)
    }catch(e:any){
       setError(e.message);
    }
    fetchData()
  },[])

Q:如何处理loading??

A:在请求后端数据但没有返回数据之后可能会有白屏,为防止白屏,可以自定义显示组件内容。

const [loading, setLoading] = useState<boolean>(false);

image.png

在发送网络请求数据之前—没有获取到数据,即可展示loading内容。

在发送网络请求数据后—得到数据,即可将loading状态关闭。

该过程可以使用三元运算符:

image.png

本文正在参加「金石计划 . 瓜分6万现金大奖」 ”

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容