React Native 如何从子组件Slider1获取pseudo值到父组件AddUserInfo使用
解决方案
最优方案:状态提升(官方推荐)
按照React单向数据流的设计原则,优先将需要跨组件共享的状态提升到公共父组件维护,这是当前场景下最轻量、可维护性最高的实现方式,不需要额外引入ref或者第三方状态管理库。
修改后父组件AddUserInfo代码
const AddUserInfo = () => { const scroll = useRef(null) // 将pseudo状态提升到父组件维护 const [pseudo, setPseudo] = useState("") return ( <View style={ styles.container }> <View style={ styles.slider }> <ScrollView ref={scroll} horizontal= {true} snapToInterval= {width} decelerationRate= "fast" showsHorizontalScrollIndicator= {false} bounces= {false} > <Animated.View style={{flex: 1, width: width }}> {/* 将状态和修改方法通过props传给子组件 */} <Slider1 style={{flex: 4}} pseudo={pseudo} onPseudoChange={setPseudo}/> <Animated.View style={{flex: 2, justifyContent: 'flex-end', alignItems: 'center'}}> <TouchableOpacity style={styles.buttonCircle} onPress={() => { // 此处直接即可使用pseudo的值 console.log('获取到的pseudo:', pseudo) if(scroll.current) { scroll.current.scrollTo({ x: width, y: 0, animated: true }); } }}/> </Animated.View> </Animated.View>
修改后子组件Slider1代码
const Slider1 = ({ pseudo, onPseudoChange, style }) => { // 子组件不再单独维护pseudo状态,直接使用父组件传入的props return ( <Animated.View style={style}> <TextInput mode="outlined" value={pseudo} label="Pseudo" placeholder="Pseudo" onChangeText= {(val) => onPseudoChange(val)} /> </Animated.View> ) }
备选方案:forwardRef + useImperativeHandle
如果Slider1内部逻辑非常复杂,pseudo状态确实不适合提升到父组件维护,可以通过ref暴露子组件内部属性的方式实现取值,实现代码如下:
修改后子组件Slider1代码
import { forwardRef, useImperativeHandle } from 'react'; // 用forwardRef包裹组件接收父级传入的ref const Slider1 = forwardRef(({ style }, ref) => { const [pseudo, setPseudo] = useState("") // 将需要暴露给父组件的方法挂载到ref上 useImperativeHandle(ref, () => ({ getPseudo: () => pseudo })) return ( <Animated.View style={style}> <TextInput mode="outlined" value={pseudo} label="Pseudo" placeholder="Pseudo" onChangeText= {(pseudo) => setPseudo(pseudo)} /> </Animated.View> ) })
修改后父组件AddUserInfo代码
const AddUserInfo = () => { const scroll = useRef(null) // 新建ref绑定到Slider1组件 const slider1Ref = useRef(null) return ( <View style={ styles.container }> <View style={ styles.slider }> <ScrollView ref={scroll} horizontal= {true} snapToInterval= {width} decelerationRate= "fast" showsHorizontalScrollIndicator= {false} bounces= {false} > <Animated.View style={{flex: 1, width: width }}> {/* 绑定ref到子组件 */} <Slider1 ref={slider1Ref} style={{flex: 4}}/> <Animated.View style={{flex: 2, justifyContent: 'flex-end', alignItems: 'center'}}> <TouchableOpacity style={styles.buttonCircle} onPress={() => { // 通过ref调用子组件暴露的方法获取pseudo const pseudo = slider1Ref.current?.getPseudo() console.log('获取到的pseudo:', pseudo) if(scroll.current) { scroll.current.scrollTo({ x: width, y: 0, animated: true }); } }}/> </Animated.View> </Animated.View>
内容的提问来源于stack exchange,提问作者Dimitri Enj
相关产品推荐
相关产品推荐

