React子组件更新父State后,二次接收服务端消息不渲染问题
问题解决方法
核心问题分析
弹窗二次无法显示,本质是子组件的弹窗状态没和父组件传入的控制状态联动,加上子组件的初始化逻辑只执行一次,后续父组件状态变化时没触发弹窗重新打开。
具体修改步骤
- 父组件:重命名易混淆的状态变量
把状态名props改成showModal(避免和组件的props参数冲突),同时清理冗余代码:
export default function App() { // 重命名状态,避免和组件props参数混淆 const [showModal, setShowModal] = useState(false) // 简化弹窗隐藏方法 const hideModal = () => { setShowModal(false) } useEffect(() => { (async () => { const newConnection = new HubConnectionBuilder() .withUrl('http://10.0.2.2:7008/ChatHub') .configureLogging(LogLevel.Debug) .withAutomaticReconnect() .build() newConnection .start() .then(async () => { await newConnection.send('AddToGroupLogin', category, email, loc) }) .catch((error) => { console.log(error) }) newConnection.on('receivemessage', (message) => { // 收到服务端消息直接设置弹窗显示 setShowModal(true) }) })() }, []) return ( <View style={styles.container}> {/* 传递重命名后的状态和方法 */} <TabTwoScreen showModal={showModal} hideModal={hideModal}></TabTwoScreen> </View> ) }
- 子组件:让弹窗状态和父组件状态联动
删掉原来仅执行一次的初始化useEffect,改为监听父组件传入的showModal状态,当它变为true时自动打开弹窗:
import React, { useEffect } from 'react' import { StyleSheet, Text, TextInput, View } from 'react-native' import { Button } from './Button' import { Modal } from './Modal' export default function TabTwoScreen({ showModal, hideModal }) { const [isModalVisible, setIsModalVisible] = React.useState(false) // 监听父组件的showModal状态,变化时同步弹窗显示状态 useEffect(() => { if (showModal) { setIsModalVisible(true) } }, [showModal]) const handleSignUp = () => { setIsModalVisible(false) hideModal() } const handleDecline = () => { setIsModalVisible(false) hideModal() } return ( <View style={styles.container}> <View style={styles.separator} /> <Modal isVisible={isModalVisible}> <Modal.Container> <View style={styles.modal}> <Modal.Header title="You're just one step away!" /> <Modal.Body> <Text style={styles.text}> Want to answer this persons request?! </Text> <TextInput style={styles.input} placeholder="email" keyboardType="email-address" /> </Modal.Body> <Modal.Footer> <View style={styles.button}> <Button title="No thanks" onPress={handleDecline} /> <Button title="Lets go!" onPress={handleSignUp} /> </View> </Modal.Footer> </View> </Modal.Container> </Modal> </View> ) }
修改逻辑说明
- 父组件状态重命名后,代码可读性提升,彻底避免了状态变量和组件props的混淆。
- 子组件通过
useEffect监听父组件的showModal状态,只要父组件将其设为true,弹窗就会自动触发显示,无论第几次收到服务端消息都能生效。 - 关闭弹窗时同时更新子组件的弹窗状态和父组件的控制状态,保证两者状态同步。
内容的提问来源于stack exchange,提问作者Riz
相关产品推荐
相关产品推荐

