Closed Resolution666 closed 2 years ago
问题描述 在使用remax写函数组件时,我在父组件中条件渲染子组件,当满足条件的子组件渲染时,在子组件中使用usePageEvent监听子组件的onShow, onReady, onLoad 等生命周期均不执行,只有 react 中提供的useEffect 执行了
示例代码 父组件 `import React, { useState, useCallback, useEffect } from 'react' import { View, Text } from 'remax/wechat' import StepOne from './StepOne'; import StepTwo from './StepTwo'; interface IProps {
}
interface IState { step: number }
const LiveDetection:React.FC = () => { const [ step, setStep ] = useState(0)
const nextStep = useCallback(() => { setStep(step => step + 1) }, [step]) const resetStep = useCallback(() => { setStep(0) }, []) useEffect(() => { return () => { console.log('unmout') resetStep() } }, []) return ( <View> { step === 0 && <StepOne nextStep={nextStep} /> } { step === 1 && <StepTwo /> } </View> )
export default LiveDetection 子组件 import * as React from 'react'; import { View, Button, Camera, createCameraContext, Text, Video, VideoProps } from 'remax/wechat'; import { usePageEvent } from 'remax/macro' import { styled } from 'linaria/react'
子组件
const BlackTip = styled(View) margin-top: 30; margin-bottom: 50; display: flex; flex-flow: column;
margin-top: 30; margin-bottom: 50; display: flex; flex-flow: column;
const BlackTipTxt = styled(View) font-size: 30px; text-align: center;
font-size: 30px; text-align: center;
const BlackTipTxtNumber = styled(View) font-size: 100px; text-align: center; margin-top: 30px;
font-size: 100px; text-align: center; margin-top: 30px;
const CameraContent = styled(View) display: flex; justify-content: center; position: relative; margin-top: 40px;
display: flex; justify-content: center; position: relative; margin-top: 40px;
const CameraContentText = styled(View) display: flex; justify-content: center; flex-flow: column; align-items: center; position: absolute; z-index: 100; font-weight: bold; font-size: 18px; color: #fff; margin-top: 50px;
display: flex; justify-content: center; flex-flow: column; align-items: center; position: absolute; z-index: 100; font-weight: bold; font-size: 18px; color: #fff; margin-top: 50px;
const CameraContainer = styled(Camera) height: 450px; width: 450px; clip-path: circle(50% at 50% 50%);
height: 450px; width: 450px; clip-path: circle(50% at 50% 50%);
const VideoContent = styled(View) display: flex; align-items: center; justify-content: center; margin-top: 50px;
display: flex; align-items: center; justify-content: center; margin-top: 50px;
const VideoContainer = styled(Video) height: 450px; width: 450px; border-radius: 50%; display: flex;
height: 450px; width: 450px; border-radius: 50%; display: flex;
const ButtonContent = styled(View) text-align: center; box-sizing: border-box; padding-left: 12px; padding-right: 12px; margin-top: 60px;
text-align: center; box-sizing: border-box; padding-left: 12px; padding-right: 12px; margin-top: 60px;
const StopButton = styled(Button) border: 1px solid #ff934a; color: #ff934a; background-color: #fff;
border: 1px solid #ff934a; color: #ff934a; background-color: #fff;
const EndButton = styled(Button) border: 1px solid #ff934a; color: #fff; background-color: #ff934a;
border: 1px solid #ff934a; color: #fff; background-color: #ff934a;
const ReScanButton = styled(Button) border: none; color: #ff934a; background-color: #fff;
border: none; color: #ff934a; background-color: #fff;
interface IProps { }
enum EMVideoStatus { INIT = 'init', ONGOING = 'ongoing', END = 'end', }
const mapConfirmTxt = {
[EMVideoStatus.ONGOING]: '结束拍摄', [EMVideoStatus.END]: '使用视频',
const StepTwo:React.FC = () => { // 创建相机上下文对象 const cameraContext = React.useRef(); cameraContext.current = createCameraContext() // 创建定时器具柄 const timer = React.useRef(); // 页面当前状态 const [ status, setStatus ] = React.useState(EMVideoStatus.INIT) // 相机是否 ready const [ ready, setReady ] = React.useState(false) // 倒计时参数 const [ countingNum, setCountingNum ] = React.useState(5) // 视频对象 const [ viderObj, setVideoObj ] = React.useState()
usePageEvent('onReady', () => { console.log('onReady =====>') })
// React.useEffect(() => { // // 绑定相机上下文对象 // cameraContext.current?.startRecord({ // success:function (res) { // console.log('startRecord=====> ', res) // } // }) // }, [])
React.useEffect(() => { if(!ready){ // 监听ready状态, 当ready为 false 时,设置定时器,执行倒计时 timer.current = setInterval(() => { setCountingNum((state) => state - 1) }, 1000) } return () => { clearInterval(timer.current) } }, [ready])
React.useEffect(() => { if(countingNum === 0 && !ready){ // 倒计时结束,改变ready状态,清除定时器,设置当前status clearInterval(timer.current) setReady(true) setStatus(EMVideoStatus.ONGOING) cameraContext.current?.startRecord({ success:function (res) { console.log('startRecord=====> ', res) } }) } }, [countingNum])
// 初始化相机参数 const initCamera = () => { setVideoObj({ src: '' }); setReady(false); setCountingNum(5) setStatus(EMVideoStatus.INIT) }
// 开始录像 const handleStartRecord = async () => { console.log(cameraContext) initCamera() }
// 结束录像 const handleStopRecord = () => { console.log(cameraContext.current) cameraContext.current?.stopRecord({ success: function (res) { console.log('stopRecord=====> ', res) setStatus(EMVideoStatus.END) setVideoObj({ src: res.tempVideoPath}) }, fail: function (error) { console.log(error) } }) }
// 摄像头在非正常终止时触发 const eventStop = () => {
} // 用户不允许使用摄像头时触发 const eventError = () => {
} // 相机初始化完成时触发 const eventInitDone = () => {
} return ( <>
问题描述 在使用remax写函数组件时,我在父组件中条件渲染子组件,当满足条件的子组件渲染时,在子组件中使用usePageEvent监听子组件的onShow, onReady, onLoad 等生命周期均不执行,只有 react 中提供的useEffect 执行了
示例代码 父组件 `import React, { useState, useCallback, useEffect } from 'react' import { View, Text } from 'remax/wechat' import StepOne from './StepOne'; import StepTwo from './StepTwo'; interface IProps {
}
interface IState { step: number }
const LiveDetection:React.FC = () => { const [ step, setStep ] = useState(0)
}
export default LiveDetection
子组件
import * as React from 'react'; import { View, Button, Camera, createCameraContext, Text, Video, VideoProps } from 'remax/wechat'; import { usePageEvent } from 'remax/macro' import { styled } from 'linaria/react'const BlackTip = styled(View)
margin-top: 30; margin-bottom: 50; display: flex; flex-flow: column;
const BlackTipTxt = styled(View)
font-size: 30px; text-align: center;
const BlackTipTxtNumber = styled(View)
font-size: 100px; text-align: center; margin-top: 30px;
const CameraContent = styled(View)
display: flex; justify-content: center; position: relative; margin-top: 40px;
const CameraContentText = styled(View)
display: flex; justify-content: center; flex-flow: column; align-items: center; position: absolute; z-index: 100; font-weight: bold; font-size: 18px; color: #fff; margin-top: 50px;
const CameraContainer = styled(Camera)
height: 450px; width: 450px; clip-path: circle(50% at 50% 50%);
const VideoContent = styled(View)
display: flex; align-items: center; justify-content: center; margin-top: 50px;
const VideoContainer = styled(Video)
height: 450px; width: 450px; border-radius: 50%; display: flex;
const ButtonContent = styled(View)
text-align: center; box-sizing: border-box; padding-left: 12px; padding-right: 12px; margin-top: 60px;
const StopButton = styled(Button)
border: 1px solid #ff934a; color: #ff934a; background-color: #fff;
const EndButton = styled(Button)
border: 1px solid #ff934a; color: #fff; background-color: #ff934a;
const ReScanButton = styled(Button)
border: none; color: #ff934a; background-color: #fff;
interface IProps { }
enum EMVideoStatus { INIT = 'init', ONGOING = 'ongoing', END = 'end', }
const mapConfirmTxt = {
}
const StepTwo:React.FC = () => {
// 创建相机上下文对象
const cameraContext = React.useRef();
cameraContext.current = createCameraContext()
// 创建定时器具柄
const timer = React.useRef();
// 页面当前状态
const [ status, setStatus ] = React.useState(EMVideoStatus.INIT)
// 相机是否 ready
const [ ready, setReady ] = React.useState(false)
// 倒计时参数
const [ countingNum, setCountingNum ] = React.useState(5)
// 视频对象
const [ viderObj, setVideoObj ] = React.useState()
usePageEvent('onReady', () => { console.log('onReady =====>') })
// React.useEffect(() => { // // 绑定相机上下文对象 // cameraContext.current?.startRecord({ // success:function (res) { // console.log('startRecord=====> ', res) // } // }) // }, [])
React.useEffect(() => { if(!ready){ // 监听ready状态, 当ready为 false 时,设置定时器,执行倒计时 timer.current = setInterval(() => { setCountingNum((state) => state - 1) }, 1000) } return () => { clearInterval(timer.current) } }, [ready])
React.useEffect(() => { if(countingNum === 0 && !ready){ // 倒计时结束,改变ready状态,清除定时器,设置当前status clearInterval(timer.current) setReady(true) setStatus(EMVideoStatus.ONGOING) cameraContext.current?.startRecord({ success:function (res) { console.log('startRecord=====> ', res) } }) } }, [countingNum])
// 初始化相机参数 const initCamera = () => { setVideoObj({ src: '' }); setReady(false); setCountingNum(5) setStatus(EMVideoStatus.INIT) }
// 开始录像 const handleStartRecord = async () => { console.log(cameraContext) initCamera() }
// 结束录像 const handleStopRecord = () => { console.log(cameraContext.current) cameraContext.current?.stopRecord({ success: function (res) { console.log('stopRecord=====> ', res) setStatus(EMVideoStatus.END) setVideoObj({ src: res.tempVideoPath}) }, fail: function (error) { console.log(error) } }) }
// 摄像头在非正常终止时触发 const eventStop = () => {
} // 用户不允许使用摄像头时触发
const eventError = () => {
} // 相机初始化完成时触发 const eventInitDone = () => {
} return ( <>