NervJS / taro

开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/
https://docs.taro.zone/
Other
35.57k stars 4.79k forks source link

Taro.eventCenter回调函数获取到useReducer的state永远都是最初始时的值 #9765

Open XingToYang opened 3 years ago

XingToYang commented 3 years ago

相关平台

字节跳动小程序

小程序基础库: 1.9.41.8 使用框架: React

复现步骤

1.在useEffect启动Taro.eventCenter监听器。2.初始化useReducer。3.改变useReducer的state。4.触发Taro.eventCenter,在Taro.eventCenter的回调函数读取useReducer的state,读到的state还是初始时的值。

期望结果

4.触发Taro.eventCenter,在Taro.eventCenter的回调函数读取useReducer的state,读得最新的state。

实际结果

4.触发Taro.eventCenter,在Taro.eventCenter的回调函数读取useReducer的state,读到的state还是初始时的值。

环境信息

👽 Taro v3.2.8

  Taro CLI 3.2.8 environment info:
    System:
      OS: macOS 11.3.1
      Shell: 5.8 - /bin/zsh
    Binaries:
      Node: 14.15.1 - /usr/local/bin/node
      Yarn: 1.22.10 - /usr/local/bin/yarn
      npm: 6.14.8 - /usr/local/bin/npm
    npmPackages:
      @tarojs/cli: 3.2.8 => 3.2.8 
      @tarojs/components: 3.2.8 => 3.2.8 
      @tarojs/mini-runner: 3.2.8 => 3.2.8 
      @tarojs/react: 3.2.8 => 3.2.8 
      @tarojs/runtime: 3.2.8 => 3.2.8 
      @tarojs/taro: 3.2.8 => 3.2.8 
      @tarojs/webpack-runner: 3.2.8 => 3.2.8 
      babel-preset-taro: 3.2.8 => 3.2.8 
      eslint-config-taro: 3.2.8 => 3.2.8 
      react: ^17.0.0 => 17.0.2 
      taro-ui: ^3.0.0-alpha.3 => 3.0.0-alpha.10 
XingToYang commented 3 years ago

import {View, Image, Text} from '@tarojs/components' import './index.less' import Taro, { useRouter } from '@tarojs/taro' import {useEffect, useReducer } from 'react'

const initState = { // repairRecordStatus rrs: 5, // insuranceClaimsStatus ics: 5, // afterSalesStatus ass: 5 }

let timeoutId = ''

const reducer = (state, action) => { const { type, ...others } = action switch (type) { case 'set': return {...state, ...others}; default: throw new Error(); } }

const EnquiryInfo = (props) => { const routeData = useRouter(); const path = routeData?.path;

const { vin, carLicense} = props; const [state, dispatch] = useReducer(reducer, initState)

useEffect(() => refreshStatuses(true), [vin])

const refreshStatuses = (isFirst: boolean) => { if (!vin) { return; }

updateRepairRecordStatus(isFirst, {})
updateInsuranceClaimStatus(isFirst, {})

}

useEffect(() => { Taro.eventCenter.on('onPageVisiblyChanged', e => { console.log('xxxx useEffect: onPageVisiblyChanged state ==>', state) console.log('xxxx useEffect: onPageVisiblyChanged e ==>', e) const { path: path2, isHide, isShow } = e; if (path2 !== path) { return; }

  if (isHide) {
    stopTiming();
    return;
  }

  if (isShow) {
    onStatusChanged()
  }
});
return () => {
  stopTiming();
  Taro.eventCenter.off('onPageVisiblyChanged');
}

}, [])

const onStatusChanged = () => { const { rrs, ics } = state let canTiming = rrs === 1 || ics == 2 canTiming = canTiming || ics === 1 || ics === 2 stopTiming() if (!canTiming) { return } // start startTiming() }

useEffect(() => { onStatusChanged() }, [state])

const handleClick = (key: string) => { if (key === 'repair' && [3,4,5].indexOf(state.rrs) >= 0) { updateRepairRecordStatus(false, {toBuy: true, licensePlate: carLicense}) return }

if (key === 'repair' && state.rrs === 0) {
  Taro.navigateTo({
    url: `/pages/maintenanceInfo/index?vin=${vin}&type=1`
  })
  return;
}

if (key === 'repair') {
  updateRepairRecordStatus(false, {})
  return;
}

if (key === 'insuranceClaim' && [3,4,5].indexOf(state.ics) >= 0) {
  updateInsuranceClaimStatus(false, {toBuy: true, licensePlate: ''})
  return
}

if (key === 'insuranceClaim' && state.ics === 0) {
  Taro.navigateTo({
    url: `/pages/maintenanceInfo/index?vin=${vin}&type=2`
  })
  return;
}

if (key === 'insuranceClaim') {
  updateInsuranceClaimStatus(false, {})
  return;
}

if (key === 'afterSales') {
  switch (state.ass) {
    case 5:
      fetchAfterSales()
      break;
    case 1:
      break;
    default:
      Taro.navigateTo({
        url: `/pages/maintenanceInfo/index?vin=${vin}&type=3`
      })
      break;
  }
}

}

const startTiming = () => { console.log('xxxxx startTiming 1 state: ', state) stopTiming() timeoutId = setTimeout(() => { console.log('xxxxx startTiming setInterval state: ', state)

  if (state.rrs === 1 || state.rrs === 2) {
    handleClick('repair')
  }
  if (state.ics === 1 || state.ics === 2) {
    handleClick('insuranceClaim')
  }
}, 5000);

}

const stopTiming = () => { clearTimeout(timeoutId) }

const updateRepairRecordStatus = async (isFirst: boolean, params: any) => { if (vin) { const {code, data} = await getRepairRecordStatus(params, vin) code === 2000 && dispatch({ type: 'set', rrs: data }) } else if (!isFirst) { Taro.showToast({ title: '请先完善车辆信息!', icon: 'none' }) } } const updateInsuranceClaimStatus = async (isFirst: boolean, params: any) => { if (vin) { const {code, data} = await getInsuranceClaimsStatus(params, vin) code === 2000 && dispatch({ type: 'set', ics: data }) } else if (!isFirst) { Taro.showToast({ title: '请先完善车辆信息!', icon: 'none' }) } } /**

export default EnquiryInfo;

XingToYang commented 3 years ago

image

Chen-jj commented 3 years ago

@XingToYang hooks 用法错了吧,useEffect 的依赖数组要加入 state

image