![](/img/trans.png)
[英]React Hooks: Best practise in passing state between children of hook component
[英]React Hooks: Passing Hook State back to Parent Component
我正在构建我的第一个 React Native 库,但它当然会带来一些问题。 这是一个用于 React Native 的小型选择器组件库(日期、时间、日期时间、列表、状态),但我需要一些关于如何进行下一步的指导。
App.js(最终会是一个 NPM 包,但使用 App 进行测试)
我想使用onValueChange
以便用户可以在从 NPM 包导入组件时使用setState
将状态设置为他们的屏幕。 截至目前,它只是将值记录到控制台(但该值未正确传递,因此不起作用)。 这就是为什么我将onValueChange
作为 ListPicker 组件道具。 我的问题在 ListPicker.js 描述中有进一步的解释。
// Imports: Dependencies
import React, { useState, useEffect } from 'react';
// Imports: Components
import { ListPicker } from './src/ListPicker';
// React Native App
export default App = () => {
// Test Data
const items = [
{ label: '1', value: '1' },
{ label: '2', value: '2' },
{ label: '3', value: '3' },
{ label: '4', value: '4' },
{ label: '5', value: '5' },
{ label: '6', value: '6' },
{ label: '7', value: '7' },
{ label: '8', value: '8' },
{ label: '9', value: '9' },
{ label: '10', value: '10' }
];
return (
<ListPicker listName="List Test" items={items} onValueChange={(value) => console.log(`Value Updated: ${value}`)}/>
);
};
列表选择器.js
这是 ListPicker 组件,从 Picker 中选择时的值是value
并使用setValue
设置。
我的问题: *如何将 React Hook 中的value
传递给父组件中的onValueChange
? 我在selectValue
方法中这样做吗?
// Imports: Dependencies
import React, { useState } from 'react';
import { Button, DatePickerAndroid, DatePickerIOS, Dimensions, Platform, Picker, SafeAreaView, StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import Modal from 'react-native-modal';
import Icon from 'react-native-vector-icons/Ionicons';
Icon.loadFont();
// Screen Dimensions
const { height, width } = Dimensions.get('window');
// Component: List Picker
export const ListPicker = (props) => {
// React Hooks: State
const [ modalVisible, toggle ] = useState(false);
const [ value, setValue ] = useState();
// React Hooks: Lifecycle Methods
// Toggle Modal
toggleModal = () => {
try {
// React Hook: Toggle Modal
toggle((modalVisible) => !modalVisible);
}
catch (error) {
console.log(error);
}
};
// Select Value
selectValue = (value) => {
try {
// React Hook: Set Value
setValue(value);
// React Props: onValueChange
// DO SOMETHING HERE??
}
catch (error) {
console.log(error);
}
};
// Render Picker Type
renderPickerType = () => {
try {
// Check Platform (iOS)
if (Platform.OS === 'ios') {
return (
<Picker
selectedValue={value}
onValueChange={this.selectValue}>
{props.items.map((item) => {
return (
<Picker.Item
label={item.label}
value={item.value}
key={item.key || item.label}
color={item.color}
/>
);
})}
</Picker>
)
}
// Check Platform (Android)
if (Platform.OS === 'android') {
}
}
catch (error) {
console.log(error);
}
};
return (
<View style={styles.container}>
<View style={styles.inputTitleContainer}>
<Text style={styles.inputTitle}>{props.listName}</Text>
</View>
<TouchableOpacity onPress={this.toggleModal} style={styles.fieldTextContainer}>
<Text style={styles.fieldText}>{value !== undefined ? value : 'Select'}</Text>
<Icon name="ios-arrow-forward" size={22} style={styles.arrowForward}/>
</TouchableOpacity>
<Modal
isVisible={modalVisible}
style={styles.modal}
>
<View style={styles.modalContainer}>
<View style={styles.pickerHeaderContainer}>
<TouchableOpacity onPress={this.toggleModal} >
<Text style={styles.doneText}>Done</Text>
</TouchableOpacity>
</View>
<View style={styles.pickerContainer}>
{this.renderPickerType()}
</View>
</View>
</Modal>
</View>
);
}
// Styles
const styles = StyleSheet.create({
container: {
display: 'flex',
width: width - 32,
marginLeft: 16,
marginRight: 16,
justifyContent: 'center',
},
modal: {
margin: 0,
},
modalContainer: {
height: '100%',
alignItems: 'center',
justifyContent: 'flex-end',
},
pickerHeaderContainer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
height: 40,
width: width,
backgroundColor: '#FAFAF8',
borderColor: '#7D7D7D',
borderBottomWidth: StyleSheet.hairlineWidth,
},
pickerContainer: {
height: 220,
width: width,
// backgroundColor: '#CFD3D9',
backgroundColor: 'white',
},
doneText: {
fontFamily: 'System',
color: '#007AFF',
fontWeight: '600',
fontSize: 17,
marginRight: 16,
},
stateContainer: {
alignItems: 'center',
width: 75,
borderColor: '#7D7D7D',
borderBottomWidth: StyleSheet.hairlineWidth,
},
inputTitleContainer: {
width: 75,
marginBottom: 4,
},
inputTitle: {
color: '#7D7D7D',
borderColor: '#7D7D7D',
fontSize: 10,
fontWeight: '600',
textTransform: 'uppercase',
},
fieldTextContainer: {
height: 40,
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 4,
borderColor: '#7D7D7D',
borderBottomWidth: StyleSheet.hairlineWidth,
},
fieldText: {
fontFamily: 'System',
fontSize: 17,
fontWeight: '400',
color: '#000000',
alignSelf: 'center',
},
arrowForward: {
color: 'black',
opacity: .3,
marginRight: 7,
},
});
是的。 只需在selectValue
方法中使用更改后的值调用props.onValueChange
selectValue
。
// Select Value
selectValue = (value) => {
// React Hook: Set Value
setValue(value);
// React Props: onValueChange
props.onValueChange(value)
};
顺便说一句,你不需要在任何地方都使用try catch
:D
onValueChange
是一个函数,当您需要根据您的代码将新值传递给父组件时,您需要调用该函数:
// 在这里做点什么??
只是props.onValueChange(value)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.