I have 2 root components in react360.I have the main panel with information and my products and i have my 3d model.I want to communicate one another.Μore specifically I just want to click on the product then the color from my 3d model changes.At this time, my 3d model has value from the store I have originally defined, but while the price is changing, it is not renewed in the 3d model.for example when the application starts the original color of my model is blue but when I click on the first item it does not change to red. Wrere is the problem?????before
after
client.js
import { ReactInstance } from "react-360-web";
import { Location } from "react-360-web";
function init(bundle, parent, options = {}) {
const r360 = new ReactInstance(bundle, parent, {
// Add custom options here
fullScreen: true,
...options
});
// Render your app content to the default cylinder surface
r360.renderToSurface(
r360.createRoot("Center", {
/* initial props */
}),
r360.getDefaultSurface()
);
r360.renderToLocation(
r360.createRoot("React3DView"),
r360.getDefaultLocation()
);
// Load the initial environment
r360.compositor.setBackground(r360.getAssetURL("360_world.jpg"));
}
window.React360 = { init };
index.js
import { AppRegistry } from "react-360";
import Center from "./components/center";
import React3DView from "./components/obj";
AppRegistry.registerComponent("Center", () => Center);
AppRegistry.registerComponent("React3DView", () => React3DView);
reducer
initialState = {
data: [
{ id: 1, value: "MILEPTY.png" },
{ id: 2, value: "cleveland.png" },
{ id: 3, value: "phila.png" },
{ id: 4, value: "raptors.png" },
{ id: 5, value: "rockets.png" }
],
currentinfo: "Hello.Press click on T-shirt to show information",
currentcolor: "blue"
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case "INFO":
if (action.key === 1) {
return {
...state,
currentinfo: "Milwaukee bucks",
currentcolor: "red"
};
}
if (action.key === 2) {
return {
...state,
currentinfo: "Cleveland Cavaliers",
currentcolor: "green"
};
}
if (action.key === 3) {
return { ...state, currentinfo: "Philadelphia 76xers" };
}
if (action.key === 4) {
return { ...state, currentinfo: "Toronto Raptors" };
}
if (action.key === 5) {
return { ...state, currentinfo: "Huston Rockets" };
}
default:
return state;
}
};
export default reducer;
centerPanel
import React from "react";
import { AppRegistry, StyleSheet, Text, View, Image, asset } from "react-360";
import Products from "./products";
import { connect } from "react-redux";
class CenterPanel extends React.Component {
render() {
return (
<View style={styles.panel}>
<View style={{ flex: 1, flexDirection: "row" }}>
<View
style={{
width: 250,
height: 600
}}
>
<Text style={{ marginTop: "100" }}>{this.props.currentinfo}</Text>
</View>
<View
style={{
width: 1000,
height: 600,
backgroundColor: "green"
}}
>
<View style={{ flex: 1, flexDirection: "row" }}>
{this.props.data.map(element => (
<Products
key={element.id}
value={element.value}
id={element.id}
/>
))}
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
panel: {
// Fill the entire surface
width: 1000,
height: 600,
backgroundColor: "rgba(255, 255, 255, 0.4)"
}
});
const mapStateToProps = state => {
return {
data: state.data,
currentinfo: state.currentinfo
};
};
export default connect(mapStateToProps)(CenterPanel);
products
import React from "react";
import { AppRegistry, StyleSheet, Text, View, Image, asset } from "react-360";
import { connect } from "react-redux";
class Products extends React.Component {
state = {
img: this.props.value
};
render() {
return (
<View
style={styles.panelimages}
onInput={() => this.props.onText(this.props.id)}
>
<Image style={styles.images} source={asset(this.state.img)} />
</View>
);
}
}
const styles = StyleSheet.create({
panelimages: {
width: 150,
height: 150,
marginTop: 200,
backgroundColor: "white"
},
images: {
width: 150,
height: 150
}
});
const mapDispatchToProps = dispatch => {
return {
onText: id => dispatch({ type: "INFO", key: id })
};
};
export default connect(
null,
mapDispatchToProps
)(Products);
center
import React from "react";
import { AppRegistry, StyleSheet, Text, View, Image, asset } from "react-360";
import { createStore } from "redux";
import { Provider } from "react-redux";
import reducer from "../store/reducer";
import CenterPanel from "./centerPanel";
// const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
const store = createStore(reducer);
export default class Center extends React.Component {
render() {
return (
<Provider store={store}>
<CenterPanel />
</Provider>
);
}
}
objpanel
import React from "react";
import {
asset,
AppRegistry,
StyleSheet,
Text,
View,
VrButton,
Image
} from "react-360";
import Entity from "Entity";
import { connect } from "react-redux";
class Object3d extends React.Component {
render() {
return (
<View>
<Entity
source={{ obj: asset("t-shirt.obj") }}
style={{
transform: [{ translate: [-3.5, -3.5, -2.8] }],
color: this.props.currentcolor -------->here is problem
}}
/>
</View>
);
}
}
const mapStateToProps = state => {
return {
currentcolor: state.currentcolor
};
};
export default connect(mapStateToProps)(Object3d);
obj
import React from "react";
import { AppRegistry, StyleSheet, Text, View, Image, asset } from "react-360";
import { createStore } from "redux";
import { Provider } from "react-redux";
import reducer from "../store/reducer";
import Object3d from "./objpanel";
// const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
const store = createStore(reducer);
export default class React3DView extends React.Component {
render() {
return (
<Provider store={store}>
<Object3d />
</Provider>
);
}
}
I've tried to do this with redux but in the end I had more problems implementing it than it was worth. In order to implement something like that you would need to follow the code that is described here:
React 360 multi panel example
Additionally, I've implemented what you are trying to do without redux. You can look at the code in this repository and also view the production link here. Its modeled after the react 360 code.
CryptoDashboardVR repo
CryptodashboardVR Multipanel synchronization
Finally, If you still need help, check out my course on React 360. I explain the concepts used. Udemy react 360.
Hope that helps. For now, I would abandon the redux approach until maybe 2.0 comes out.
Related
I'm trying to replicate this example. It won't work somehow. From components higher in the hierarchy to lower ones, I have three files:
index.js:
import React, { Component } from "react"
import { SelectableGroup } from "react-selectable-fast"
import List from "../components/List"
const items = [
{
player: "Dirk Nowitzki",
year: 1999,
},
{
player: "Magic Johnson",
year: 1980,
},
{
player: "Michael Jordan",
year: 1990,
},
]
const IndexPage = () => (
<SelectableGroup
className="main"
clickClassName="tick"
// enableDeselect
// tolerance={this.state.tolerance}
// globalMouse={this.state.isGlobal}
// allowClickWithoutSelected={false}
// duringSelection={this.handleSelecting}
duringSelection={() => {
console.log("DURING")
}}
// onSelectionClear={this.handleSelectionClear}
onSelectionFinish={() => {
console.log("FINISH")
}}
>
<List items={items} />
</SelectableGroup>
)
export default IndexPage
List.js
import React, { Component } from "react"
import SelectableComponent from "./Film"
export default class List extends Component {
render() {
console.log(this.props.items)
return (
<>
{this.props.items.map((item, i) => (
<SelectableComponent key={i} player={item.player} year={item.year} />
))}
</>
)
}
}
Player.js
import React from "react"
import { createSelectable } from "react-selectable-fast"
const Player = ({ selectableRef, selected, selecting }) => (
<div
ref={selectableRef}
style={{
border: "1px solid blue",
width: "300px",
height: "300px",
float: "left",
}}
className="tick"
>
{console.log(selected)}
{console.log(selecting)}
</div>
)
export default createSelectable(Player)
It doesn't throw any errors, but the console.log in Player.js are always undefined. OnSelectionFinish and DuringSelection work fine, at least the console.log are coming through.
The variable names need to be changed they are isSelected and isSelecting in your Player.js
A good rule of thumb is to print your whole props object when debugging.
Further code can be found on the library's github page.
import React from 'react'
import { TSelectableItemProps, createSelectable } from 'react-selectable-fast'
class SomeComponent extends Component<TSelectableItemProps> {
render() {
const { selectableRef, isSelected, isSelecting } = this.props
return <div ref={selectableRef}>...</div>
}
}
export default createSelectable(SomeComponent)
I am trying to make a custom input component with onChangeText but whenever I start typing in the textInput box I get an error. I have checked the code many times and everything looks fine to me.
import React from "react";
import { TextInput, StyleSheet } from "react-native";
const defaultInput = props => (
<TextInput
underlineColorAndroid="transparent"
{...props}
style={[styles.input, props.style]}
/>
)
const styles = StyleSheet.create({
input: {
width: "100%",
borderWidth: 1,
borderColor: "#eee",
padding: 5,
marginTop: 8,
marginBottom: 8
}
});
export default defaultInput;
This is my sub component where I am using my custom component.
import React, { Component } from "react";
import { View, TextInput, Button, StyleSheet } from "react-native";
import DefaultInput from "../UI/DefaultInput/DefaultInput";
const placeInput = props =>(
<DefaultInput
placeholder="Place Name"
value={props.placeName}
onChangeText={props.onChangeText}
/>
)
export default placeInput;
This is the screen where I am using my sub component.
import React, { Component } from 'react'
import { Text, View, TextInput, Button, StyleSheet, ScrollView, Image } from 'react-native'
import { connect } from 'react-redux'
import placeImage from '../../asset/pic.jpg'
import PlaceInput from '../../component/PlaceInput/PlaceInput'
import { addPlace } from '../../store/actions/index'
import { Navigation } from 'react-native-navigation'
// import DefaultInput from '../../component/UI/DefaultInput/DefaultInput'
import HeadingText from '../../component/UI/HeadingText/HeadingText'
import MainText from '../../component/UI/MainText/MainText'
import PickImage from '../../component/PickImage/PickImage'
import PickLocation from '../../component/PickLocation/PickLocation'
class SharePlace extends Component {
state={
placeName:""
}
constructor(props) {
super(props);
this.props.navigator.setOnNavigatorEvent(this.OnNavigatorEvent);
}
placeNameChangedHandler = val => {
this.setState({
placeName: val
});
};
OnNavigatorEvent = (event) => {
console.log(event);
if (event.type === "NavBarButtonPress") {
if (event.id === "sideDrawerToggle") {
this.props.navigator.toggleDrawer({
side: "left"
})
}
}
}
placeAddedHandler = () => {
if(this.state.placeName.trim() !== "")
{
this.props.onAddPlace(this.state.placeName);
}
}
render() {
return (
// <ScrollView contentContainerStyle={styles.conatiner}>
<ScrollView>
<View style={styles.conatiner}>
<MainText>
<HeadingText>Share a place with us!</HeadingText>
</MainText>
<PickImage />
<PickLocation />
<PlaceInput
placeName={this.state.placeName}
onChangeText={this.placeNameChangedHandler}
/>
<View style={styles.button}>
<Button title="share the place" onPress={this.placeAddedHandler} />
</View>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
conatiner: {
flex: 1,
alignItems: "center"
},
placeholder: {
borderWidth: 1,
borderColor: "black",
backgroundColor: "#eee",
width: "80%",
height: 150
},
button: {
margin: 8
},
imagePreview: {
width: "100%",
height: "100%"
}
})
const mapDispatchToProps = dispatch => {
return {
onAddPlace: (placeName) => dispatch(addPlace(placeName))
}
}
export default connect(null, mapDispatchToProps)(SharePlace)
This is the error I am getting.
ExceptionsManager.js:63 Invariant Violation: TextInput(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
This error is located at:
in TextInput (at DefaultInput.js:5)
in defaultInput (at PlaceInput.js:7)
in placeInput (at SharePlace.js:60)
in RCTView (at View.js:60)
in View (at SharePlace.js:54)
in RCTScrollContentView (at ScrollView.js:791)
in RCTScrollView (at ScrollView.js:887)
in ScrollView (at SharePlace.js:53)
in SharePlace (created by Connect(SharePlace))
in Connect(SharePlace) (at Navigation.js:83)
in Provider (at Navigation.js:82)
in _class2 (at renderApplication.js:33)
in RCTView (at View.js:60)
in View (at AppContainer.js:102)
in RCTView (at View.js:60)
in View (at AppContainer.js:122)
in AppContainer (at renderApplication.js:32)
Using typescript,
import {TextInput, TextInputProps, View} from "react-native";
declare a props interface:
interface Props extends TextInputProps {}
// This ensures that all the properties associated with react-native's
// TextInput component, are associated with your custom-input component as well.
decalare your custom-input component:
const CustomInput = (props: Props) => {
<TextInput onChangeText={props.onChangeText} placeholder={props.placeholder} style={[props.style]} />
}
export default CustomInput;
use your custom-input component in LoginScreen.tsx say;
import React from "react";
import CustomInput from "../CustomInput";
const LoginScreen = () => {
const handleChange = (value: string) =>{
....
}
return(
<CustomInput placeholder="email" onChangeText={value => handleChange(value) />
)
your code working fine as the way I ran it, maybe you have problem to import PlaceInput or DefaultInput:
import React, { Component } from 'react';
import { View, Text, FlatList, ScrollView,TextInput, Image,StyleSheet } from 'react-native';
export default class Test extends Component {
constructor(props) {
super(props);
this.state = {
placeName: ""
}
}
placeNameChangedHandler = val => {
this.setState({
placeName: val
});
};
render() {
return (
<View>
<PlaceInput
placeName={this.state.placeName}
onChangeText={this.placeNameChangedHandler}
/>
</View>
);
}
}
const PlaceInput = props => (
<DefaultInput
placeholder="Place Name"
value={props.placeName}
onChangeText={props.onChangeText}
/>
)
const DefaultInput = props => (
<TextInput
underlineColorAndroid="transparent"
{...props}
style={[styles.input, props.style]}
/>
)
const styles = StyleSheet.create({
input: {
width: "100%",
borderWidth: 1,
borderColor: "#eee",
padding: 5,
marginTop: 8,
marginBottom: 8
}
});
Wizard and WizardPage
I am trying to build a generic Wizard and WizardPages to be generic a reusable across my app. I think the Wizard component as the one in charge of managing the state, and the WizardPage that is going to work as a wrapper, and will render Back, Cancel and Next buttons. It's suppose that the Next button (maybe the Back too) should dispatch an redux action. This action, could be different depending on the component being wrapped. This is what i have (not complete version):
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import withWizardLayout from '../../hoc/WithWizardLayout';
class Wizard extends Component {
constructor(props) {
super(props);
this.state = {
page: 0,
};
}
nextPage = () => {
this.setState({ page: this.state.page + 1 });
};
previousPage = () => {
this.setState({ page: this.state.page - 1 });
};
render() {
const { wizardPages } = this.props;
const { page } = this.state;
const wizardItem = wizardPages[page];
const nextPage = this.nextPage;
const previousPage = this.previousPage;
const ComponentWrapped = withWizardLayout(wizardItem.ComponentWrapped, nextPage, previousPage);
return (
<ComponentWrapped />
);
}
}
export default Wizard;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { compose } from 'react-apollo';
import { connect } from 'react-redux';
import { Flex, Box } from 'reflexbox';
import { BlueRoundButton, GreyRoundButton } from '../components/Button';
export default function withWizardLayout(ComponentDependent, nextPageCallBack, previousPageCallback) {
class WizardPage extends Component {
previousPage = () => {
};
nextPage = () => {
this.props.test();
};
render() {
const { ComponentWrapped, isFirstPage, isLastPage } = ComponentDependent;
return (
<Flex column>
<ComponentWrapped
isLastPage={isLastPage}
isFirstPage={isFirstPage}
>
<Flex justify='flex-end'>
<Flex mr='auto' w={0.1}>
<GreyRoundButton style={{ fontWeight: '500', position: 'relative', top: '10%' }}>Back</GreyRoundButton>
</Flex>
<Flex w={0.08} mr={2} align='center' justify='center' style={{ textAlign: 'center' }}>
<span>Cancel</span>
</Flex>
<Flex w={0.15} justify='center'>
<BlueRoundButton onClick={this.nextPage} style={{ position: 'relative', top: '10%', fontWeight: '500' }}>Continue</BlueRoundButton>
</Flex>
</Flex>
</ComponentWrapped>
</Flex>
);
}
}
CustomersContainer
import { compose } from 'react-apollo';
import { connect } from 'react-redux';
import CustomerImport from '../components/Settings/CustomerImport';
import { withWizardLayout } from '../hoc/WithWizardLayout';
const mapStateToProps = null;
const mapDispatchToProps = dispatch => (
{
test: () => (dispatch(console.log("hi"))),
}
);
export default compose(connect(null, mapDispatchToProps))(CustomerImport);
Connected Component
import React, { Component } from 'react';
import styled from 'styled-components';
import {
SettingBlock,
NotifyBlock,
SuccessMessage,
ErrorMessage,
Instructions,
} from './styles';
import ExcelUploader from '../ExcelUploader';
const ProgressBar = styled.div`
width: 0;
height: 30px;
background-color: Green;
`;
const ExcelWrapper = styled.div`
margin-bottom: 4rem;
`;
export default class CustomerImport extends Component {
constructor(props) {
super(props);
this.state = {
progress: 0,
notify: {
success: {
message: '',
active: false,
},
error: {
message: '',
active: false,
},
},
};
}
render() {
const { success, error } = this.state.notify;
const ButtonsWrapper = this.props.children;
return (
<div>
<NotifyBlock>
<SuccessMessage className={success.active ? 'active' : null}>{success.message}</SuccessMessage>
<ErrorMessage className={error.active ? 'active' : null}>{error.message}</ErrorMessage>
</NotifyBlock>
<SettingBlock>
<h3>
Import your customers
</h3>
<ProgressBar style={{ width: `${this.state.progress}%` }} />
<Instructions>
Select an Excel file containing your customer information.
Need a template? Grab one here.
</Instructions>
<ExcelWrapper>
<ExcelUploader />
</ExcelWrapper>
{ButtonsWrapper}
</SettingBlock>
</div>
);
}
}
This is how i am supposed to render the Generic Wizard, we can have X wizardPages:
const wizardPages = [
{
ComponentWrapped: CustomersContainer,
isFirstPage: false,
isLastPage: false,
},
];
<Wizard wizardPages={wizardPages} />
The problem with this approach, is that i want on the onClick of the buttons in withWizardLayout:
1) Execute the callback on the Father (that's possible, i am passing as prop the handler)
2) Call the dispatch action received of the container. (i am not able not access the dispatched action, in this case, this.props.test)
How can i refactor this, to think a generic way to handle this? I think another ways to refactor this (having different withWizardLayout functions, but i am having render problems on the console).
Maybe i didn't architect this in the best way.
Help!
I think I'm close with setting up React Redux for my React native app. I currently have this set up.
Here I define the action that I want to call.
/* actions/mapActions.js */
export const setMarker = selectedMarker => {
return {
type: 'SET_MARKER',
selectedMarker
}
}
Here I define the container for the component that I want to use the store in.
//containers/mapContainers.js
import { connect } from 'react-redux';
import { setMarker } from './actions/mapActions'
import HomeScreen from './screens/HomeScreen'
const mapStateToProps = state => {
return {
selectedMarker: state.marker
}
}
const mapDispatchToProps = dispatch => {
return {
markerClick: (marker) => {
dispatch(setMarker(marker))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen)
Here I combine the reducers as I've seen in a tutorial I've been following.
//reducers/index.js
import { combineReducers } from 'redux'
import mapReducer from './mapReducer'
const dabApp = combineReducers({
mapReducer
})
export default dabApp
Here I define the reducer for the component.
//reducers/mapReducers.js
const mapReducer = (state = [], action) => {
switch (action.type) {
case 'SET_MARKER':
return [
...state,
{
marker: action.marker
}
]
default:
return state
}
}
export default mapReducer
Main entry point to the application.
//App.js
// other imports here
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import snapApp from './reducers';
let store = createStore(dabApp);
export default class App extends React.Component {
state = {
isLoadingComplete: false,
};
render() {
return (
<Provider store={store}>
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
{Platform.OS === 'android' &&
<View style={styles.statusBarUnderlay} />}
<RootNavigation />
</View>
</Provider>
);
}
}
const styles = StyleSheet.create({
//Styles.
});
Here I define the component.
//Standard react imports.
import { MapView } from 'expo';
import { connect } from 'react-redux';
export default class HomeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
//Set states.
};
}
render() {
return (
<View style={styles.container}>
<MapView
//MapView info
>
{this.state.markers.map((marker) =>
<MapView.Marker
key={marker.id}
coordinate={marker.coordinate}
onPress={() => {this.props.markerClick(marker); this.props.navigation.navigate('Information');}}>
</MapView.Marker>
)}
</MapView>
</View>
);
}
}
const styles = StyleSheet.create({
//Styles.
});
The error I get is that the function 'markerClick' is undefined in the Map.Marker onPress prop. I have followed the tutorial religiously and can't find the solution to this.
The tutorial that I was following was this one on the official redux site. http://redux.js.org/docs/basics/ExampleTodoList.html.
Has anyone encountered the same issue?
Unfortunately, Harry's answer hasn't solved the issue.
I console.log(this.props) and I get this:
Still is undefined. When I console.log(this.props") I get:
Object {
"navigation": Object {
"dispatch": [Function anonymous],
"goBack": [Function goBack],
"navigate": [Function navigate],
"setParams": [Function setParams],
"state": Object {
"key": "Home",
"routeName": "Home",
},
},
"screenProps": undefined,
"selectedMarker": [Function dispatch],
"type": "SET_MARKER",
}
so I don't even see the function on my props.
As you can see, the function is not defined on this.props.
Thanks,
I feel like you're making more steps than needed.
Try something like this:
import React, { Component } from 'react';
import { MapView } from 'expo';
import { connect } from 'react-redux';
import { View, StyleSheet } from 'react-native';
import { setMarker } from './actions/mapActions'
class HomeScreen extends Component {
onPress(marker) {
this.props.setMarker(marker);
this.props.navigation.navigate('Information');
}
render() {
return (
<View style={styles.container}>
<MapView>
{this.state.markers.map((marker) => (
<MapView.Marker
key={marker.id}
coordinate={marker.coordinate}
onPress={() => { this.onPress(marker); }}
/>
)
)}
</MapView>
</View>
);
}
}
const styles = StyleSheet.create({
//Styles.
});
export default connect(null, setMarker)(HomeScreen);
You don't need to define a function that then dispatches an action, you can just connect the action to the component.
It's also much nicer to just have everything in the same file instead of having a separate mapContainers.js
I've been working on my first React Native project. It is a Multiscreen App, and one of the screens requires some data, which I'm passing from the parent screen. But the issue is that when I receive the data in the child screen, and try to save the value in the screen's state, the app crashes. As soon as I remove the code that accesses the state, it does not crash. Here's the code:
renderRow(object) { //Calling the second screen when the user touches
const { navigate } = this.props.navigation;
return(
<TouchableOpacity onPress={() => navigate('ViewRecord', { key: object.key })}> //Sending the parameter
<Image
styleName="large-square"
source={{ uri: object.record.image }} >
<Text style={styles.designNumberHeading}>{object.record.designNumber}</Text>
</Image>
</TouchableOpacity>
);
}
Here is the code of the Child Screen:
'use-strict'
import React, { Component } from 'react';
import {
StyleSheet,
View,
KeyboardAvoidingView,
ScrollView,
TouchableHighlight,
Text,
FlatList,
} from 'react-native';
import {
Heading,
Title,
TextInput,
Button,
Image,
NavigationBar,
ListView,
TouchableOpacity,
Icon,
Lightbox,
Overlay,
} from '#shoutem/ui';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import NavBar from '../components/NavBar.js';
import { firebaseApp } from '../config/firebase.js';
export default class ViewRecord extends Component{
constructor(props) {
super(props);
this.state={
designNumber: '',
dates: [],
quantity: 0,
karigars: [],
colour:'',
amount: '',
description: '',
editMode: false,
};
this.updateStateAfterGettingData = this.updateStateAfterGettingData.bind(this);
}
getData() {
const { params } = this.props.navigation.state; //Accessing the parameters
console.log('Key: ', params.key);
let databaseRef = firebaseApp.database().ref(params.key);
databaseRef.once('value', (snap) => {
console.log('Inside Event Listener');
this.updateStateAfterGettingData(snap); //Setting the state. (The App crashes if this statement is executed)
});
}
updateStateAfterGettingData(snap) {
this.setState({
designNumber: snap.val().designNumber,
dates: snap.val().dates,
quantity: snap.val().quantity,
karigars: snap.val().karigars,
colour: snap.val().colour,
amount: snap.val().amount,
materials: snap.val().materials,
description: snap.val().description,
});
console.log(this.state);
}
render() {
const { goBack } = this.props.navigation;
this.getData();
if (!this.state.editMode) {
return(
<View style={styles.container}>
<NavBar title="View Record" hasHistory={true} goBack={() => goBack()}/>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFFFFF',
},
})
Here is the code of the StackNavigator:
import { StackNavigator } from 'react-navigation';
import CreateRecord from '../screens/CreateRecord.js';
import Records from '../screens/Records.js';
import ViewRecord from '../screens/ViewRecord.js';
export const Navigator = StackNavigator({
Records: { screen: Records },
CreateRecord: { screen: CreateRecord },
ViewRecord: { screen: ViewRecord },
},
{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
Now, how can I manipulate the state of the ViewRecord.js class when accepting parameters?
PS: I am using Expo along with Create React Native App