theme: channing-cyan
省流:本文搭建了简易购物车,并将页面数据替换为服务器中数据。
前言:实现react+ts中项目的logo与字体设置
在项目中通常是使用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;
}
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用来保存点击的布尔类型状态。
再设置点击按钮时更改state状态即可。
又是由于该项目语言为ts,所以少不了每一个约束。当点击按钮后传来的e形参,我们要保证点击的元素是SPAN标签,否则无法展示item栏。此处引申出target与currentTarget两个属性:
-
target是事件发生的元素本身;
-
currentTarget是事件处理的元素,也就是触发该事件的button。
为了更好的理解这两个属性,使用如下代码进行测试:
<button className={styles.button}
onClick={this.handleClick}>
<FiShoppingCart /> //购物车组件
<span>购物车 2 (件)</span>
</button>
通过点击两次button按钮测试两者的区别,控制台输出如下:
所以得出结果,我们需要保证点击的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栏的显示与隐藏。
获取网络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会报错,所以要规避这个问题,使用其他方式。
解决方式:将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);
在发送网络请求数据之前—没有获取到数据,即可展示loading内容。
在发送网络请求数据后—得到数据,即可将loading状态关闭。
该过程可以使用三元运算符:
本文正在参加「金石计划 . 瓜分6万现金大奖」 ”
暂无评论内容