modify a child class using the parent pseudo class in React-JSS - css-in-js

I was trying to modify class attribute of a child element when the parent element is hovered.
Here is one of my attempts at the solution.
const useStyles = makeStyles((theme) => ({
parent: {
"&:hover child": {
marginLeft: '0px'
},
child: {
marginLeft: '-99px'
}
})

Reference a class name with a $ like so:
const styles = {
parent: {
'&:hover $child_class_name': {
marginLeft: '0px'
},
child_class_name: {
marginLeft: '-99px'
}
}

Related

Can't test Apollo GraphQL query's loading state

guys. I have a query that gets data from backend, while query didn't get data I'm showing '...Loading' text. Now I want to test it, but I can't. Test's logic is: if loading state is true, check if we have '...Loading' text.
Here is my query:
const [getCards, { data: cardsData, error: cardsError, loading: cardsLoading }] = useLazyQuery(
GET_LIST,
{
fetchPolicy: 'no-cache',
}
);
Here is my check of loading state:
if (cardsLoading) {
return (
<View
style={{
width: '100%',
height: '100%',
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text>...Loading</Text>
</View>
);
}
And finally here is my test:
const getCardsMock = [
{
request: {
query: GET_LIST,
},
result: {
cards: {
id: 0,
name: 'card',
},
}
},
];
it('Loading state test', async () => {
const component = renderer.create(
<MockedProvider mocks={getCardsMock} addTypename={false}>
<HomeViewApollo />
</MockedProvider>
);
const tree = component.toJSON();
expect(tree.children).toContain('...Loading');
});
After running test I got an error telling me that expected value isn't equal to received value. Received value is array with component, that I render, if loading is done.
I'm not sure but looks like that component's loading state never changes during the test. Do you have an idea how to fix it?
I rewrote test like that
it('Loading state test', async () => {
let wrapper = render(
<MockedProvider mocks={[getCardsMock]} addTypename={false}>
<HomeViewApollo />
</MockedProvider>
);
await waitFor(() => [
expect(wrapper.queryByTestId('loadingIndicator')).toBeTruthy()
]);
});
Now it works.

React Native Table with Row Selection

I am trying to create a React Native screen that allows the user to select which items to send to the server for batch processing.
My thought was to have a table, and allow the user to select the rows they want, then click a button to submit to the server.
I need the state to contain a list of the ids from those rows, so that I can use it to allow the user to send a request with that array of ids.
A mock-up of my code is below, but it doesn't work. When the update of state is in place, I get an error of "selected items is not an object". When it is commented out, of course the state update doesn't work, but it also doesn't set the value of the checkbox from the array if I hard code it in the state initialization (meaning is 70 is in the array, the box is still not checked by default), and it does allow the box to get checked but not unchecked. How do I get it working?
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import CheckBox from '#react-native-community/checkbox';
import { Table, Row, TableWrapper, Cell } from 'react-native-table-component';
import moment from 'moment';
class FruitGrid extends Component {
constructor(props) {
super(props);
}
state = {
selectedItems : [70],
data: []
};
refresh() {
let rows = [
[69,'David','Apples'],
[70,'Teddy','Oranges'],
[73,'John','Pears']
];
this.setState({data: rows});
}
componentDidMount() {
this.refresh();
}
setSelection(id) {
const { selectedItems } = this.state;
if (id in selectedItems)
{
this.setState({selectedItems: selectedItems.filter(i => i != id)});
}
else
{
this.setState({selectedItems : selectedItems.push(id)});
}
}
render() {
const { selectedItems, data } = this.state;
let columns = ['',
'Person',
'Fruit'];
return (
<View style={{ flex: 1 }}>
<Table borderStyle={{borderWidth: 2, borderColor: '#c8e1ff'}}>
<Row data = {columns} />
{
data.map((rowData, index) =>
(
<TableWrapper key={index} style={styles.row}>
<Cell key={0} data = {<CheckBox value={rowData[0] in selectedItems} onValueChange={this.setSelection(rowData[0])} />} />
<Cell key={1} data = {rowData[1]} textStyle={styles.text}/>
<Cell key={2} data = {rowData[2]} textStyle={styles.text}/>
</TableWrapper>
)
)
}
</Table>
</View>
);
}
}
export default FruitGrid;
const styles = StyleSheet.create({
btn: { width: 58, height: 18, backgroundColor: '#8bbaf2', borderRadius: 2 },
btnText: { textAlign: 'center', color: '#000000' },
text: { margin: 6 },
row: { flexDirection: 'row' },
});
I introduced my own module for this feature from which you will be able to select row easily and much more.
You can use this component like this below
import DataTable, {COL_TYPES} from 'react-native-datatable-component';
const SomeCom = () => {
//You can pass COL_TYPES.CHECK_BOX Column's value in true/false, by default it will be false means checkBox will be uncheck!
const data = [
{ menu: 'Chicken Biryani', select: false }, //If user select this row then this whole object will return to you with select true in this case
{ menu: 'Chiken koofta', select: true },
{ menu: 'Chicken sharwma', select: false }
]
const nameOfCols = ['menu', 'select'];
return(
<DataTable
onRowSelect={(row) => {console.log('ROW => ',row)}}
data={data}
colNames={nameOfCols}
colSettings={[{name: 'select', type: COL_TYPES.CHECK_BOX}]}
/>
)
}
export default SomeCom;
React Native DataTable Component
Thanks to a friend, I found 3 issues in the code that were causing the problem:
When checking to see if the array contains the object, I first need to check that the array is an array and contains items. New check (wrapped in a function for reuse):
checkIfChecked(id, selectedItems)
{
return selectedItems?.length && selectedItems.includes(id);
}
The state update was modifying the state without copying. New state update function:
setSelection(id) {
const { selectedItems } = this.state;
if (this.checkIfChecked(id,selectedItems))
{
this.setState({selectedItems: selectedItems.filter(i => i != id)});
}
else
{
let selectedItemsCopy = [...selectedItems]
selectedItemsCopy.push(id)
this.setState({selectedItems : selectedItemsCopy});
}
}
The onValueChange needed ()=> to prevent immediate triggering, which lead to a "Maximum Depth Reached" error. New version
onValueChange={()=>this.setSelection(rowData[0])} />}
The full working code is here:
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import CheckBox from '#react-native-community/checkbox';
import { Table, Row, TableWrapper, Cell } from 'react-native-table-component';
import moment from 'moment';
class FruitGrid extends Component {
constructor(props) {
super(props);
}
state = {
selectedItems : [],
data: []
};
refresh() {
let rows = [
[69,'David','Apples'],
[70,'Teddy','Oranges'],
[73,'John','Pears']
];
this.setState({data: rows});
}
componentDidMount() {
this.refresh();
}
setSelection(id) {
const { selectedItems } = this.state;
if (this.checkIfChecked(id,selectedItems))
{
this.setState({selectedItems: selectedItems.filter(i => i != id)});
}
else
{
let selectedItemsCopy = [...selectedItems]
selectedItemsCopy.push(id)
this.setState({selectedItems : selectedItemsCopy});
}
}
checkIfChecked(id, selectedItems)
{
return selectedItems?.length && selectedItems.includes(id);
}
render() {
const { selectedItems, data } = this.state;
let columns = ['',
'Person',
'Fruit'];
return (
<View style={{ flex: 1 }}>
<Table borderStyle={{borderWidth: 2, borderColor: '#c8e1ff'}}>
<Row data = {columns} />
{
data.map((rowData, index) =>
(
<TableWrapper key={index} style={styles.row}>
<Cell key={0} data = {<CheckBox value={this.checkIfChecked(rowData[0],selectedItems)} onValueChange={()=>this.setSelection(rowData[0])} />} />
<Cell key={1} data = {rowData[1]} textStyle={styles.text}/>
<Cell key={2} data = {rowData[2]} textStyle={styles.text}/>
</TableWrapper>
)
)
}
</Table>
</View>
);
}
}
export default FruitGrid;
const styles = StyleSheet.create({
btn: { width: 58, height: 18, backgroundColor: '#8bbaf2', borderRadius: 2 },
btnText: { textAlign: 'center', color: '#000000' },
text: { margin: 6 },
row: { flexDirection: 'row' },
});

How do I get access to to this.props.navigation if I'm on my RootPage?

I need to pass this.props.navigation to a helper function. However, I'm currently sitting on the root page, which initially creates the stackNavigator. So far I've tried importing Navigator, NavigatorActions and withNavigation from react-navigation and then sending it/them along as a parameter to my helper function, but I keep getting the error message: cannot read property 'state' of undefined.
Here is my RootPage code that is relevant:
/**
* RootPage has the Navigator. So it controls navigation.
*/
import React, { Component } from 'react';
import {
Platform,
BackHandler,
View,
Animated,
StyleSheet,
Image,
TouchableWithoutFeedback,
TouchableOpacity,
Alert
} from 'react-native';
import { connect } from 'react-redux';
import { BoxShadow } from 'react-native-shadow';
import { NavigationActions } from 'react-navigation';
import { vsprintf } from 'sprintf-js';
import RootNavigator from './RootNavigator';
//Test Component
import TestPageFactory from '../TestPage/TestPageFactory';
// Components
import XXBluetoothManager, { XXBluetoothEventEmitter } from '../../nativeComponents/XXBluetooth/XXBluetooth';
import XXText from '../../components/XXText/XXRobotoText';
import XXSyncXXerlay from '../../components/XXSyncXXerlay/XXSyncXXerlay';
// Actions
import { logout } from '../../actions/user';
import { closeSyncModal, toggleRootMenu, openRootMenu, closeRootMenu } from '../../actions/page';
// Utils
import { LAYOUTINFO } from '../../utils/layoutinfo';
import { generateElevationStyle } from '../../utils/util';
import { NavUtils } from '../../utils/navutils';
import { StatusBarManager } from '../../utils/statusbarmanager';
// Config
import { DEVICEINFO } from '../../config';
// Localization
import I18n from '../../localization/i18n';
import { aDeviceHasBeenConnectedFunc } from '../../actions/device';
// Constants
const DEFAULT_PROFILE_IMAGE = require('../../images/profile-image/user.png');
const HEIGHT_RATIO = DEVICEINFO.IS_EXTRA_SMALL_SCREEN ? 0.5 : (DEVICEINFO.SCREEN_HEIGHT >= 667 ? (DEVICEINFO.SCREEN_HEIGHT / 667) : 0.7);
class RootPage extends Component {
static getDerivedStateFromProps(nextProps, prevState) {
let shouldLoadingBeVisible = nextProps.pageStatus && nextProps.pageStatus.isUpdateRequested ? true : false;
if (!nextProps.profile && shouldLoadingBeVisible === prevState.loadingVisible) {
return null;
}
return {
profileImage: nextProps.profile && nextProps.profile.profileImage ?
{ uri: nextProps.profile.profileImage } : DEFAULT_PROFILE_IMAGE,
profileName: nextProps.profile && nextProps.profile.profileName ? nextProps.profile.profileName : '',
loadingVisible: shouldLoadingBeVisible,
};
}
constructor(props) {
super(props);
this.routeStatusBarStyle = 'dark-content';
this.state = {
animatedPosition: new Animated.ValueXY(0, 0),
profileImage: DEFAULT_PROFILE_IMAGE,
profileName: '',
deviceAddress: undefined,
isMenuVisible: false,
loggingOut: false,
device: undefined,
};
}
componentDidMount() {
if (Platform.OS === 'android') {
this.initAndroidHardwareBackEvent();
}
// this.initializeBluetooth();
}
componentWillUnmount() {
this.destroyBluetooth();
}
componentDidUpdate(prevProps, prevState) {
if (this.state.loggingOut) {
if (this.props.signinStatus && !this.props.signinStatus.isLoginSuccess) {
this.setState({ loggingOut: false }, () => {
this.onPressMenu('EntryPage');
});
}
}
if (this.props.pageStatus.isMenuVisible != null && prevState.isMenuVisible !== this.props.pageStatus.isMenuVisible) {
this.setState({ isMenuVisible: this.props.pageStatus.isMenuVisible }, () => {
this.onUpdateMenu(this.props.pageStatus.isMenuVisible);
});
}
// console.log('what are the prev state here? ", ', prevState)
/*
NOTE: We need to know when an item has been connected, if an item has not been connected, we should
make the hearing test available
*/
}
render() {
return (
<View style={styles.rootView}>
{this.renderRootMenu()}
<Animated.View style={[styles.animatedView, { left: this.state.animatedPosition.x, top: this.state.animatedPosition.y }]}>
{this.renderXXerlay()}
{this.renderNavigator()}
</Animated.View>
{this.renderSyncXXerlay()}
</View>
);
}
updateStatusBarStyle(pageId) {
let newStatusBarStyle = 'dark-content';
if (pageId === 'EntryPage') {
newStatusBarStyle = 'light-content';
}
if (newStatusBarStyle !== this.routeStatusBarStyle) {
this.routeStatusBarStyle = newStatusBarStyle;
StatusBarManager.setStyle(newStatusBarStyle, false)
}
}
renderRootMenu() {
return (
<View style={styles.menuView}>
{this.renderMenuTopArea()}
{this.renderMenuBottomArea()}
</View>
)
}
renderMenuTopArea() {
if (DEVICEINFO.IS_ANDROID && (Platform.Version === 19 || Platform.Version === 20)) {
return this.renderMenuTopAreaKitKat();
}
return this.renderMenuTopAreaDefault();
}
renderMenuTopAreaDefault() {
return (
<View style={[styles.menuTopArea, generateElevationStyle(1.5)]}>
{this.renderProfileImage()}
</View>
)
}
renderMenuTopAreaKitKat() {
let shadowOptions = {
width: DEVICEINFO.SCREEN_WIDTH,
height: (DEVICEINFO.SCREEN_HEIGHT * 0.35) + 2,
color: '#000',
border: 2,
opacity: 0.05,
radius: 1,
y: -2.5,
};
return (
<BoxShadow setting={shadowOptions}>
<View style={styles.menuTopArea}>
{this.renderProfileImage()}
</View>
</BoxShadow>
)
}
renderMenuBottomArea() {
return (
<View style={styles.menuBottomArea}>
{this.renderMenuContents()}
</View>
)
}
renderMenuContents() {
const menuData = this.generateMenuData();
let renderOutput = [];
for (let i = 0, len = menuData.length; i < len; i++) {
if (this.state.deviceAddress && menuData[i].onlyNotConnected) {
continue;
}
let extraStyle = {};
if (i === 0) {
let extraStyleMarginTop = DEVICEINFO.IS_EXTRA_SMALL_SCREEN ? 16 : 26;
extraStyle['marginTop'] = extraStyleMarginTop * LAYOUTINFO.DESIGN_HEIGHT_RATIO;
}
renderOutput.push(
<TouchableOpacity
key={menuData[i].text}
activeOpacity={0.8}
underlayColor='transparent'
onPress={() => { menuData[i].onPressMenu() }}
style={[styles.menuButtonTouch, extraStyle]}>
<View style={styles.menuButtonView}>
<Image
source={menuData[i].icon}
style={[styles.menuIcon]} />
<XXText style={[styles.menuText]}>{menuData[i].text}</XXText>
</View>
</TouchableOpacity>
)
}
return renderOutput;
}
generateMenuData() {
return [
this.generateMenuItem(I18n.t('home'), require('../../images/menu-home.png'), 'HomePage'),
this.generateMenuItem(I18n.t('tutorial'), require('../../images/menu-tutorial.png'), 'SelectTutorialPage'),
this.generateMenuItem(I18n.t('item_list'), require('../../images/menu-add-item.png'), 'itemListPage'),
this.generateMenuItem(I18n.t('report'), require('../../images/menu-report.png'), 'ReportDetailPage'),
this.generateTestPageOnly(I18n.t('hearing_test'), require('../../images/menu-demotest.png')),
this.generateMenuItem(I18n.t('equalizer'), require('../../images/menu-sound.png'), 'SoundPage'),
this.generateMenuItem(I18n.t('support'), require('../../images/menu-support.png'), 'SupportPage'),
this.generateMenuItem(I18n.t('account_settings'), require('../../images/menu-settings.png'), 'SettingsPage'),
{
text: I18n.t('logout'),
icon: require('../../images/menu-logout.png'),
onPressMenu: () => {
Alert.alert(
I18n.t('item'),
I18n.t('logout_confirmation'),
[
{ text: I18n.t('cancel'), onPress: () => { } },
{ text: I18n.t('logout'), onPress: () => { this.onPressLogout() } }
]
)
}
},
];
}
generateTestPageOnly(label, icon) {
let deviceAddress;
let versionData;
// console.log('what is the props here: ', this.props.devices)
function loopThruObject(objectOfDevices) {
for (let [key, value] of Object.entries(objectOfDevices)) {
for (let [newKey, newValue] of Object.entries(value)) {
if (newKey === 'macAddress') {
deviceAddress = newValue;
}
if (newKey === 'version')
versionData = newValue
}
}
return;
}
loopThruObject(this.props.devices)
let currentDevice = this.props.devices[deviceAddress];
let newParams = {
navIndex: 1,
device: currentDevice
};
if (this.props.aDeviceHasBeenConnected === true) {
return {
text: label,
icon: icon,
onPressMenu: () => {
let testPageIdentifier = TestPageFactory.getIdentifier({ isDemo: false, versionData: versionData });
console.log('what is the testPage identifier: ', this.props.navigation)
// NavUtils.push(NavigationActions, testPageIdentifier, { device: currentDevice });
NavigationActions.dispatch({ type: 'Navigation/NAVIGATE', routeName: 'FittingTestPage', params: newParams })
}
}
}
if (this.props.aDeviceHasBeenConnected === false) {
return {
text: 'N/A',
icon: icon,
onPressMenu: () => {
}
}
}
}
generateMenuItem(label, icon, onPressId, onlyNotConnected = false) {
return {
text: label,
icon: icon,
onPressMenu: () => {
this.onPressMenu(onPressId);
},
onlyNotConnected
}
}
renderProfileImage() {
imageSource = this.state.profileImage;
let deviceCount = Object.keys(this.props.devices).length;
let deviceConnectionString = this.generateConnectedString(deviceCount);
return (
<View style={styles.profileImageSubContainer}>
<Image
key={this.state.profileImage.uri}
source={imageSource}
style={styles.profileImage} />
{/* <XXText style={[styles.profileText]} fontWeight='Regular'>{this.state.profileName}</XXText> */}
<XXText style={[styles.deviceText]} fontWeight={'Light'}>{deviceConnectionString}</XXText>
</View>
)
}
generateConnectedString(deviceCount) {
let deviceConnectionString;
if (deviceCount === 1) {
deviceConnectionString = vsprintf(I18n.t('one_item_connected_format_str'), deviceCount.toString());
}
else {
deviceConnectionString = vsprintf(I18n.t('items_connected_format_str'), deviceCount.toString());
}
return deviceConnectionString;
}
renderNavigator() {
return (
<RootNavigator
ref={nav => {
this.navigator = nav;
}}
onNavigationStateChange={(prevState, currentState) => {
this.handleNavSceneChange(prevState, currentState);
}} />
)
}
handleNavSceneChange(prevState, currentState) {
const currentScreen = NavUtils.getCurrentRouteNameFromState(currentState);
this.currentPageId = currentScreen;
this.updateStatusBarStyle(currentScreen);
}
renderXXerlay() {
// Workaround for Android position absolute bug
// issue : https://github.com/facebook/react-native/issues/8923
let visible = this.state.isMenuVisible;
return (
<TouchableWithoutFeedback
onPress={() => { this.hideMenu() }}>
<View style={[styles.XXerlayView, { height: visible ? null : 0 }]} />
</TouchableWithoutFeedback>
)
}
renderSyncXXerlay() {
let visible = this.props.pageStatus.syncModal;
if (!visible) {
return null;
}
return (
<XXSyncXXerlay
visible={visible} />
)
}
//
// EVENTS
//
onPressMenu(pageId) {
requestAnimationFrame(() => {
if (this.currentPageId !== pageId) {
if (pageId === 'DemoTestPage') {
NavUtils.push(this.navigator, pageId);
}
else {
NavUtils.resetTo(this.navigator, pageId);
}
this.updateStatusBarStyle(pageId);
}
this.hideMenu();
});
}
onPressLogout() {
this.setState({ loggingOut: true }, () => {
this.props.logout();
});
}
onUpdateMenu(isMenuVisible) {
if (isMenuVisible === undefined || this.previousMenuVisible === isMenuVisible) {
return;
}
this.previousMenuVisible = isMenuVisible;
// When menu needs to be opened
if (isMenuVisible) {
StatusBarManager.setStyle('light-content', isMenuVisible);
Animated.timing(
this.state.animatedPosition,
{
tXXalue: {
// Animate the RootPage to the right.
// x: 317 / 375 * DEVICEINFO.SCREEN_WIDTH,
// y: 126 / 667 * DEVICEINFO.SCREEN_HEIGHT,
x: 317 / 375 * DEVICEINFO.SCREEN_WIDTH,
y: 1 / 1000 * DEVICEINFO.SCREEN_HEIGHT
},
// duration: 300
// debugging mode
duration: 300
}
).start();
return;
}
// When menu needs to be closed
StatusBarManager.setStyle(this.routeStatusBarStyle, isMenuVisible);
Animated.timing(
this.state.animatedPosition,
{
tXXalue: {
x: 0,
y: 0
},
duration: 300
}
).start();
}
//
// Methods
//
initializeBluetooth() {
// Event listeners for XXBluetoothManager
this.itemDeviceStatusChanged = XXBluetoothEventEmitter.addListener('itemDeviceStatusChanged', event => {
// console.log('ROotpage; . initializeBluetooth: ', event)
this.getConnectedDevice();
});
this.getConnectedDevice();
}
destroyBluetooth() {
if (this.itemDeviceStatusChanged) {
this.itemDeviceStatusChanged.remXXe();
}
}
getConnectedDevice() {
console.log('when does getconnectedDevice get fired inside rootpage? :D', this.props)
XXBluetoothManager.getDeviceAddress((error, address) => {
if (error) {
// Not connected
this.setState({ deviceAddress: null });
return;
}
// console.log('when can we read error, address', error, address)
this.setState({ deviceAddress: address });
});
}
initAndroidHardwareBackEvent() {
BackHandler.addEventListener('hardwareBackPress', () => {
if (!this.navigator) {
return false;
}
if (this.navigator.state.index > 0) {
const backAction = NavigationActions.back({
key: null
});
this.navigator.dispatch(backAction);
return true;
}
return false;
});
}
toggleMenu() {
this.props.toggleRootMenu();
}
hideMenu() {
this.props.closeRootMenu();
}
}
const mapStateToProps = (state) => {
return {
signinStatus: state.page.signin,
pageStatus: state.page.root,
profile: state.user.profile,
devices: state.device.devices,
aDeviceHasBeenConnected: state.device.aDeviceHasBeenConnected,
}
}
const mapDispatchToProps = (dispatch) => {
return {
logout: () => {
dispatch(logout());
},
closeSyncModal: () => {
dispatch(closeSyncModal());
},
toggleRootMenu: () => {
dispatch(toggleRootMenu());
},
openRootMenu: () => {
dispatch(openRootMenu());
},
closeRootMenu: () => {
dispatch(closeRootMenu());
},
}
}
export default connect(mapStateToProps, mapDispatchToProps)(RootPage);
const styles = StyleSheet.create({
rootView: {
flex: 1,
flexDirection: 'column',
},
menuView: {
width: DEVICEINFO.SCREEN_WIDTH,
height: '100%',
backgroundColor: '#aab942',
position: 'absolute',
top: 0,
left: 0
},
menuTopArea: {
backgroundColor: '#b7c846',
// height: DEVICEINFO.SCREEN_HEIGHT * 0.35,
height: DEVICEINFO.SCREEN_HEIGHT * 0.28,
width: '100%',
flexDirection: 'column',
},
menuBottomArea: {
// backgroundColor: '#aab942',
width: '100%',
flex: 1,
flexDirection: 'column',
},
animatedView: {
position: 'relative',
flex: 1,
flexDirection: 'column',
backgroundColor: '#fff'
},
profileImageSubContainer: {
height: '100%',
flexDirection: 'column',
justifyContent: 'center',
marginLeft: 40,
marginTop: 10,
},
profileImage: {
width: DEVICEINFO.IS_EXTRA_SMALL_SCREEN ? 70 : 80,
height: DEVICEINFO.IS_EXTRA_SMALL_SCREEN ? 70 : 80,
borderRadius: (DEVICEINFO.IS_EXTRA_SMALL_SCREEN ? 70 : 80) / 2
},
profileText: {
marginTop: DEVICEINFO.IS_EXTRA_SMALL_SCREEN ? 6 : 16,
fontSize: Math.min(LAYOUTINFO.DESIGN_WIDTH_RATIO * 20, 21),
color: '#fff',
backgroundColor: 'transparent'
},
deviceText: {
marginTop: DEVICEINFO.IS_EXTRA_SMALL_SCREEN ? 6 : 16,
fontSize: Math.min(LAYOUTINFO.DESIGN_WIDTH_RATIO * 14, 15),
color: '#fff',
backgroundColor: 'transparent'
},
menuContainer: {
flex: 1,
width: '100%',
height: '100%',
flexDirection: 'column',
alignItems: 'flex-start',
},
// menubutton
menuButtonTouch: {
marginTop: 25 * HEIGHT_RATIO,
marginLeft: 38,
},
menuButtonView: {
flexDirection: 'row',
alignItems: 'center'
},
menuIcon: {
width: 18,
height: 18,
resizeMode: 'contain'
},
// menubuttontext
menuText: {
marginLeft: 17,
fontSize: Math.min(LAYOUTINFO.DESIGN_WIDTH_RATIO * 22, 22),
color: '#fff'
},
XXerlayView: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
width: null,
height: null,
backgroundColor: 'rgba( 255, 255, 255, 0.0001 )',
zIndex: 9999
}
});
Here is the RootNavigator page
import { Platform } from 'react-native';
import { StackNavigator } from 'react-navigation';
// Pages
import EntryPage from '../EntryPage/EntryPage';
import SigninPage from '../SigninPage/SigninPage';
import SignupPage from '../SignupPage/SignupPage';
import ReportSinglePage from '../ReportSinglePage/ReportSinglePage';
import HomePage from '../HomePage/HomePage';
import VolumePage from '../VolumePage/VolumePage';
import ReportPage from '../ReportPage/ReportPage';
import ReportDetailPage from '../ReportDetailPage/ReportDetailPage';
import ItemListPage from '../ItemListPage/ItemListPage';
import AddItemPage from '../AddItemPage/AddItemPage';
import SupportPage from '../SupportPage/SupportPage';
import SettingsPage from '../SettingsPage/SettingsPage';
import SoundPage from '../SoundPage/SoundPage';
import VerticalSoundPage from '../SoundPage/VerticalSoundPage';
import SoundSyncPage from '../SoundSyncPage/SoundSyncPage';
import TestPage from '../TestPage/TestPage';
import iOSTestPage from '../TestPage/iOSTestPage';
import FittingTestPage from '../TestPage/FittingTestPage';
import SendResultSlide from '../SoundSyncPage/SendResultSlide';
import ModePage from '../ModePage/ModePage';
import PolicyPage from '../PolicyPage/PolicyPage';
import PrivacyPage from '../PrivacyPage/PrivacyPage';
import TermsAndConditionsPage from '../TermsAndConditionsPage/TermsAndConditionsPage';
import SelectTutorialPage from '../TutorialPage/SelectTutorialPage';
import PreparingTutorial from '../TutorialPage/PreparingTutorial';
import AddItemTutorial from '../TutorialPage/AddItemTutorial';
import HearingTestTutorial from '../TutorialPage/HearingTestTutorial';
import ReportTutorial from '../TutorialPage/ReportTutorial';
import EqualizerTutorial from '../TutorialPage/EqualizerTutorial';
import AddItemTutorialCompletion from '../TutorialPage/AddItemTutorialCompletion';
import AddItemTutorialFailure from '../TutorialPage/AddItemTutorialFailure';
import HearingTestTutorialCompletion from '../TutorialPage/HearingTestTutorialCompletion';
// import RootPage from '../RootPage/RootPage';
const RootNavigator = StackNavigator(
{
// RootPage: {screen: RootPage},
EntryPage: { screen: EntryPage },
SignupPage: { screen: SignupPage },
HomePage: { screen: HomePage },
TestPage: { screen: TestPage },
iOSTestPage: { screen: iOSTestPage },
FittingTestPage: { screen: FittingTestPage },
ReportPage: { screen: ReportPage },
ReportDetailPage: { screen: ReportDetailPage },
ReportSinglePage: { screen: ReportSinglePage },
ItemListPage: { screen: ItemListPage },
AddItemPage: { screen: AddItemPage },
SoundPage: { screen: VerticalSoundPage },
SoundSyncPage: { screen: SoundSyncPage },
SupportPage: { screen: SupportPage },
SettingsPage: { screen: SettingsPage },
VolumePage: { screen: VolumePage },
SendResultSlide: { screen: SendResultSlide },
PolicyPage: { screen: PolicyPage },
PrivacyPage: { screen: PrivacyPage },
TermsAndConditionsPage: { screen: TermsAndConditionsPage },
SelectTutorialPage: { screen: SelectTutorialPage },
PreparingTutorial: { screen: PreparingTutorial },
AddItemTutorial: { screen: AddItemTutorial },
HearingTestTutorial: { screen: HearingTestTutorial },
ReportTutorial: { screen: ReportTutorial },
EqualizerTutorial: { screen: EqualizerTutorial },
AddItemTutorialCompletion: { screen: AddItemTutorialCompletion },
AddItemTutorialFailure: { screen: AddItemTutorialFailure },
HearingTestTutorialCompletion: { screen: HearingTestTutorialCompletion },
},
{
initialRouteName: 'EntryPage',
navigationOptions: {
header: null,
}
},
{
headerMode: 'none'
}
);
export default RootNavigator;
And just in case, here is the helper function this I'm trying to use:
static push(navigator, pageId, params = {}) {
let newParams = { navIndex: 1 };
if (navigator.state.index) {
newParams.navIndex = navigator.state.index + 1;
}
else if (navigator.state.params && navigator.state.params.navIndex) {
newParams.navIndex = navigator.state.params.navIndex + 1;
}
Object.assign(newParams, params);
navigator.dispatch({ type: 'Navigation/NAVIGATE', routeName: pageId, params: newParams });
}

how to pass form data from screen1 to screen2 in react native?

how to pass form data from screen1 to screen2 in react native ? I have following code in scrren1 I want posted amount data in screen2. Please let me know how can I pass data on screen2 and receive it in react native?
import React, { Component } from 'react';
import { Button, View, Text, StyleSheet } from 'react-native';
import t from 'tcomb-form-native'; // 0.6.9
const Form = t.form.Form;
const User = t.struct({
amount: t.String,
});
const formStyles = {
...Form.stylesheet,
formGroup: {
normal: {
marginBottom: 10
},
},
controlLabel: {
normal: {
color: 'blue',
fontSize: 18,
marginBottom: 7,
fontWeight: '600'
},
// the style applied when a validation error occours
error: {
color: 'red',
fontSize: 18,
marginBottom: 7,
fontWeight: '600'
}
}
}
const options = {
fields: {
amount: {
label: "Enter Amount You want to Top up",
error: 'Please add amount to proceed ahead!'
},
},
stylesheet: formStyles,
};
class HomeScreen extends Component {
static navigationOptions = {
title: 'Home',
};
handleSubmit = () => {
const value = this._form.getValue();
console.log('value: ', value);
}
render() {
return (
<View style={styles.container}>
<Form
ref={c => this._form = c}
type={User}
options={options}
/>
<Button
title="Pay Now"
onPress={this.handleSubmit}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
marginTop: 50,
padding: 20,
backgroundColor: '#ffffff',
},
});
export default HomeScreen;
It depends if you want to pass data between Parent to Child, Child to Parent or Between Siblingsā€Š
I suggest you to read Passing Data Between React Components, old but this article did help me to understand the logic behind passing data as it's not as easy to implement as in other programming languages.
Excerpt using props:
class App extends React.Component {
render() {
[... somewhere in here I define a variable listName
which I think will be useful as data in my ToDoList component...]
return (
<div>
<InputBar/>
<ToDoList listNameFromParent={listName}/>
</div>
);
}
}
Now in the ToDoList component, use this.props.listNameFromParent to access that data.
You have many ways to send informations from one screen to another in React Native.
eg.
Use React Navigation to navigate between your scenes. You will be able to pass params to your components, which will be accessible in the navigation props when received.
this.props.navigation.navigate({routeName:'sceneOne', params:{name} });
You can also send directly props to a component, and treat them in it. In your render section of your first component, you could have something like this :
<myComponent oneProps={name}/>
In that example, you will receive the props "oneProps" in your second component and you will be able to access it that way :
type Props = {
oneProps: string,
}
class myComponent extends React.Component<Props> {
render() {
console.log('received sent props', oneProps);
return (
<View> // display it
<Text>{this.props.oneProps}</Text>
</View>
);
};
}
These are only two effective solutions, but there are a lot more.
Hope it helped you :)
Have a good day

How to use react-native multiple checkbox and get the selected Id

i have used react-native-select-multiple. but not working, How do i use multiple checkbox in react native and get the select multiple id and pass to next page..?
this is how to use the library, get selected items, pass the items selected and get the items on the next page.
const fruits = ['Apples', 'Oranges', 'Pears', 'banana']
this.state = {
selectedFruits: [],
}
onSelectionsChange = (selectedFruits) => {
// selectedFruits is array of { label, value }
this.setState({
selectedFruits
})
}
<
SelectMultiple
items = {
fruits
}
rowStyle = {
{
backgroundColor: 'transparent'
}
}
labelStyle = {
{
color: 'white'
}
}
checkboxStyle = {
{
borderColor: 'white',
backgroundColor: 'white'
}
}
style = {
{
borderWidth: 1,
borderColor: 'white',
width: setWidth,
height: setHeight
}
}
selectedItems = {
this.state.selectedFruits
}
onSelectionsChange = {
this.onSelectionsChange
}
/>
navigate('Screen', {
fruits: this.state.selectedFruits
} //using react-navigation. or Actions.Screen({fruits: this.state.selectedFruits})//using react-native-router-flux
this.props.navigation.state.params.fruits //using react-navigation or this.props.fruits//using react-native-router-flux