Taro Cross-segment Development Exploration 8 - Promise Waiting for Requests and Mini Program Parent-Child Component Value Transfer Exploration

Get into the habit of writing together! This is the 14th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .

foreword

Yesterday, we implemented the login interception and whitelist processing of the applet. Today, we will optimize the pit left yesterday, and then write a method to pass the value between parent and child components.

Regarding the handling of the problem of passing an empty token when the request is not completed - promise handling

I will explain the reasons and solutions carefully from the following aspects

the cause of the problem

When we call the back-end interface according to the initial method, the whole process is asynchronous. At this point, when we return the value, the backend has not finished processing our request, and our value will not change.

The solution - promise

When we encapsulate a unified request, we have already used promise to encapsulate it. Here we also use promise to solve the problem that asynchronous requests are executed downwards without executing the method. If you don’t know promises, you can check the new features of ES6 and learn about them. promise

final request/index.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: "您已被限制5秒内不可以访问接口",
        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: "请求失败:" + res.data.error,
                  icon: "none",
                });
            }
          } else {
            resolve(backEndRes.data);
          }
          resolve(res.data);
        } else {
          Taro.showToast({ title: "请求失败:" + res.data.error, icon: "none" });
        }
      })
      .catch((err) => {
        Taro.showToast({ title: "网络错误,提示:" + 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 };
复制代码

Briefly explain

  • Add async before the request method to identify it as an asynchronous function
  • Add the await method where you call to get the token
  • Modify the method of getting the token to be the method that returns the promise

Now let's talk about the more important content today, passing values ​​between parent and child components

Business scene

We have many business scenarios that require passing values ​​between parent and child components. It is more common that after the parent component obtains the list, the parent component is passed in to get the details when clicking on the word component. After the child component updates the corresponding data, the parent component needs to be refreshed or the child component needs to be closed from the parent component.

Let's take a look at the common methods of Vue

  • Pass the parent component ref to the child component and then call the method assignment of the child component, for examplethis.$refs("child").open(id)
  • Pass parameters through the prop property of the child component, for example<child id={chooseData.id}>
  • The state manager passes parameters. This way of passing parameters is relatively small, but generally more complex projects often use more

Implementation of parameter passing using react-based parent-child components

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", name: "第3个商品", price: 300, num: 2 },
      { id: "4", name: "第4个商品", price: 400, num: 1 },
    ]);
  }, []);
  return (
    <View className="shop-cart">
      {shopCartList.map((item,index) => (<ShopCartItem item={item}></ShopCartItem>)
      )}
      <Text>共{shopCartList.length}条数据</Text>
    </View>
  );
}
复制代码

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}</Text>
      </View>
    );
  }
}

export default ShopCartItem;

复制代码

Epilogue

I don’t have enough time every day, and I am hovering on the edge of pigeons every day. Let’s complete the requirements of parent data transfer to child components first, and add the code of child transfer to father tomorrow (in fact, it has been developed, but the function has not been implemented). Welcome everyone to pay more attention and like!

Guess you like

Origin juejin.im/post/7086484265440903176