Make writing a habit together! This is the 14th day of my participation in the “Gold Digging Day New Plan · April More Text Challenge”. Click here for more details.

preface

Yesterday we realized the small program login interception and whitelist processing, today we first optimize the pit left yesterday, and then to write a parent-child component transfer worth method

Handle the issue of passing tokens empty when the request is not completed – Promise handle

I will explain the reasons and solutions in detail from the following aspects

The cause of the problem

The whole process is asynchronous when we call the back-end interface as we did at the beginning. At this point, when we return the value, the back end has not finished processing our request, our value will not change

Solution — Promise

We’ve used promises to encapsulate unified requests, and we’re also using promises to solve the problem of asynchronous requests executing down unexecuted methods. If you’re not familiar with promises, check out the new ES6 feature for yourself

The final request/index. The TSX

import Taro from "@tarojs/taro"; const white_res_code = [200, 10001, 10002]; const white_uri = ["/auth/login"]; import { loginByCode } from ".. /api/user"; function getTokenByApi() { return new Promise((resolve) => { Taro.login({ success: (res) => { loginByCode(res.code).then((res) => { resolve(res["token"]); }); }}); }); } async function request(url, data, method): Promise<any> { let notNeedTokenflag = white_uri.filter((item) => url.includes(item)).length > 0; let token = Taro.getStorageSync("token"); if (! notNeedTokenflag && (! token || token === "")) { token = await getTokenByApi(); Taro.setStorageSync("token", token); } const header = { "content-type": "application/json", }; if (! notNeedTokenflag) { header["Authorization"] = `Bearer ${token}`; } return new Promise((resolve) => { let retryCount = Taro.getStorageSync("returCount") || 0; if (retryCount >= 10) { setTimeout(() => { Taro.removeStorageSync("returCount"); }, 5000); Return Taro. ShowToast ({title: "you have been restricted from accessing the interface for 5 seconds ", icon:" None ",}); } Taro.request({ url, data, method, header, }) .then((res) => { if (res.statusCode === 200) { const backEndRes = res.data; const resCode = backEndRes.code; if (! white_res_code.includes(resCode)) { switch (resCode) { case 500: return Taro.showToast({ title: + backendres. MSG, icon: "none",}); case 401: Taro.removeStorageSync("token"); Taro.setStorageSync("returCount", retryCount + 1); request(url, data, method); Return Taro. ShowToast ({title: "backendres. MSG, icon: "none",}); case 403: Taro.removeStorageSync("token"); Taro.setStorageSync("returCount", retryCount + 1); request(url, data, method); Return Taro. ShowToast ({title: "backendres. MSG, icon: "none",}); Default: return Taro. ShowToast ({title: "request failed :" + res.data.error, icon: "none",}); } } else { resolve(backEndRes.data); } resolve(res.data); } else {Taro. ShowToast ({title: "request failed :" + res.data.error, icon: "none"}); }}). The catch ((err) = > {Taro. ShowToast ({title: "network error, note:" + err. ErrMsg, icon: "none"}); }); }); } function get(url) { return request(url, null, "GET"); } function post(url, data) { return request(url, data, "POST"); } function del(url) { return request(url, null, "DELETE"); } function put(url, data) { return request(url, data, "POST"); } export { get, post, del, put };Copy the code

Just a quick explanation

  • Add async before the request method to identify it as an asynchronous function
  • Add await method in the call where the token is obtained
  • Modify the method that gets the token to return a promise

Let’s focus on today’s topic, passing values between parent and child components

The business scenario

We have many business scenarios where values are passed between parent and child components. It is common for the parent component to fetch the list, and then the parent component to fetch the details when it clicks on it. After the child component has updated the corresponding data, you need to refresh the parent component or close the child component from the parent.

Let’s take a look at the usual vUE approach

  • The parent component ref to the child component and then call the child component method assignment, for examplethis.$refs("child").open(id)
  • Pass parameters through the prop property of the child component, for example<child id={chooseData.id}>
  • State manager parameter passing, which is less, but generally more complex projects tend to use

Implementation of parent/child component parameter transfer using React

Shopping cart Index page

import { View, Text } from "@tarojs/components"; import { useEffect, useState } from "react"; import ShopCartItem from "./shop-cart-item"; import "./index.scss"; export default function ShopCart() { const [shopCartList, setShopCartList] = useState([]); UseEffect () => {setShopCartList([{id: "1", name: "1", price: 100, num: 4}, {id: "2", name: "2", price: 200, num: 3}, {id: "3", the name: "third" goods, price: 300, num: 2}, {id: "4", the name: "fourth" goods, price: 400, num: 1},]); } []); return ( <View className="shop-cart"> {shopCartList.map((item,index) => (<ShopCartItem item={item}></ShopCartItem>) )} <Text> total {shopcartList. length} data </Text> </View>); }Copy the code

Shopping cart Item page

import { View, Text } from "@tarojs/components"; import { Component } from "react"; import "./index.scss"; class ShopCartItem extends Component { constructor(props) { super(props); item: { } } render() { const item = this.props["item"]; Return (<View className="shop-cart-item"> <Text> item name {item.name}</Text> </View>); } } export default ShopCartItem;Copy the code

conclusion

Every day is not enough time, every day hovering at the edge of the dove, today first to complete the parent data to child component requirements, tomorrow to supplement the parent code (actually developed, but the function has not been realized). Welcome everyone to pay attention to praise!