React-native how to use a state value in another javasript file - javascript

I want to use a value, from the file Step3.js in Step4.js, the value can change after user input in Step3. But how can I use this value in Step4?
I have tried some things, but I guess I miss the point here, so hopefully somebody can help me out with this.
This is my code:
App.js:
import React, { Component } from 'react'
import { AppRegistry, StyleSheet, View, Text } from 'react-native'
import { ViewPager } from 'rn-viewpager'
import StepIndicator from 'react-native-step-indicator'
import Step1 from "./Step1";
import Step2 from "./Step2";
import Step3 from "./Step3";
import Step4 from "./Step4";
const PAGES = [{id: 1, page: <Step1/>},{id: 2, page: <Step2/>}, {id: 3, page: <Step3/>}, {id: 4, page: <Step4/>}];
const firstIndicatorStyles = {
stepIndicatorSize: 30,
currentStepIndicatorSize: 40,
separatorStrokeWidth: 5,
currentStepStrokeWidth: 3,
separatorFinishedColor: '#4aae4f',
separatorUnFinishedColor: '#a4d4a5',
stepIndicatorFinishedColor: '#4aae4f',
stepIndicatorUnFinishedColor: '#a4d4a5',
stepIndicatorCurrentColor: '#ffffff',
stepIndicatorLabelFontSize: 15,
currentStepIndicatorLabelFontSize: 15,
stepIndicatorLabelCurrentColor: '#000000',
stepIndicatorLabelFinishedColor: '#ffffff',
stepIndicatorLabelUnFinishedColor: 'rgba(255,255,255,0.5)',
labelColor: '#666666',
labelSize: 12,
currentStepLabelColor: '#4aae4f'
};
export default class App extends Component {
constructor (props) {
super(props);
this.state = {
currentPosition: 0,
stepCount: 4,
}
}
componentWillReceiveProps (nextProps, nextState) {
if (nextState.currentPosition != this.state.currentPosition) {
if (this.viewPager) {
this.viewPager.setPage(nextState.currentPosition)
}
}
}
render () {
return (
<View style={styles.container}>
<ViewPager
style={{ flexGrow: 1 }}
ref={viewPager => {
this.viewPager = viewPager
}}
onPageSelected={page => {
this.setState({ currentPosition: page.position })
}}
>
{PAGES.map(page => this.renderViewPagerPage(page))}
</ViewPager>
<View style={styles.stepIndicator}>
<StepIndicator
customStyles={firstIndicatorStyles}
currentPosition={this.state.currentPosition}
stepCount={this.state.stepCount}
labels={['Kleur', 'Vorm', 'Moeite', 'Overzicht']}
/>
</View>
</View>
)
}
renderViewPagerPage = (data) => {
console.log(data);
console.log(this.state.currentPosition);
return (
<View key={data.id}>
{data.page}
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff'
},
stepIndicator: {
marginVertical: 20
},
});
Step3.js:
export function getSelected3() {
return this.state.selected;
}
class Step3 extends Component {
constructor(props){
super(props);
this.state = {
happy: {
"id" : "1",
"name" : "happy",
"src" : require('../../assets/images/makkelijk.png')
},
normal: {
"id" : "2",
"name" : "normal",
"src" : require('../../assets/images/gemiddeld.png'),
},
sad: {
"id" : "3",
"name" : "sad",
"src" : require('../../assets/images/moeilijk.png'),
},
selected: {
"id" : "4",
"name" : "",
"src" : require('../../assets/images/moeilijk.png'),
},
};
}
onPress = (item) => {
this.state.selected.name = item.name;
this.state.selected.src = item.src;
alert(this.state.selected.name);
};
render() {
return (
<View style={styles.container}>
<View style={[styles.box]}>
<TouchableHighlight onPress={() => this.onPress(this.state.happy)}>
<Image
style={styles.image}
source={this.state.happy.src}
/>
</TouchableHighlight>
</View>
<View style={[styles.box]}>
<TouchableHighlight onPress={() => this.onPress(this.state.normal)}>
<Image
style={styles.image}
source={this.state.normal.src}
/>
</TouchableHighlight>
</View>
<View style={[styles.box]}>
<TouchableHighlight onPress={() => this.onPress(this.state.sad)}>
<Image
style={styles.image}
source={this.state.sad.src}
/>
</TouchableHighlight>
</View>
</View>
)
}
}
So I want to use the date from the state in Step3 selected into Step4.js, How can I Do this?
Step4.js:
class Step4 extends Component {
constructor(props) {
super(props);
this.state = {
value3: {
"id": "3",
"name" : "",
"src" : "",
},
};
}
render() {
let test = getSelected3();
this.state.value3.src = value3.src;
return (
<View style={styles.container}>
<View style={[styles.box]}>
<TouchableHighlight>
<Image
style={styles.image}
source={this.state.value3.src}
/>
</TouchableHighlight>
</View>
<View style={[styles.box]}>
<TouchableHighlight>
<Image
style={styles.image}
source={this.state.value3.src}
/>
</TouchableHighlight>
</View>
<View style={[styles.box]}>
<TouchableHighlight>
<Image
style={styles.image}
source={this.state.value3.src}
/>
</TouchableHighlight>
</View>
</View>
)
}

Suggest you to make Step3 and Step4 components stateless which will receive only props and create a component Stepper which will render both Step3 and Step4. Stepper component will do all the state manipulations.
class Stepper extents Component {
render() {
const { state1, state2, state3, state4, onPress } = this.state;
return [
<Step3 state1={state1} state3={state3} onPress={onPress} />,
<Step4 state2={state2} state4={state4} />
];
}
}
And Step3 would look like this:
const Step3 = ({ state1, state2, onPress }) => {
return (<TouchableHighlight onPress={onPress}></TouchableHighlight);
};
Hope you get the idea.

Copy pasting my answer from a similar question
I usually create a global.js containing:
module.exports = {
step3State: null,
};
And get the value of the state on the screen
render() {
GLOBAL.step3State = this;
//enter code here
}
Now you can use it anywhere like so:
GLOBAL.step3State.setState({
var: value
});
or
Global.step3State.state.value

Related

React Native/TypeScript - How to manage state in functional component and apply flexible style with FlatList

Can anyone tell me how to solve these things?
1.if the list is pressed, I'd like to change the background color of the list
beige(#FFF5E7) to white(#FBFBFB)
2.Also, I'd like to change the read value of the Object fales to true with useState
Problem is that if I pressed the list, whole background color of the list will be changed.
index.tsx
import React, { useState } from 'react';
import { Text, View, TouchableOpacity, FlatList } from 'react-native';
import { useNavigation } from '#react-navigation/native';
import { DETAIL } from '../../sample';
import { Object } from './sample';
export default function sample() {
const [state, setState] = useState(Object);
const navigation = useNavigation();
let Element;
const renderItem = ({ item }) => {
const readState = () => {
navigation.navigate(NOTICE_DETAIL);
const readValue = [...state];
let value = { ...readValue[0] };
value.read = true;
readValue[0] = value;
setState(readValue);
};
if (state[0].read) {
Element = (
<TouchableOpacity onPress={readState}>
<View style={[styles.row, { backgroundColor: '#FBFBFB' }]}>
<View style={styles.container}>
<View style={styles.end}>
<Text style={styles.text}>{item.text}</Text>
<Text style={styles.time}>{item.time}</Text>
</View>
<Text style={styles.content}>{item.content}</Text>
</View>
</View>
</TouchableOpacity>
);
} else {
Element = (
<TouchableOpacity onPress={readState}>
<View style={[styles.row, { backgroundColor: '#FFF5E7' }]}>
<View style={styles.container}>
<View style={styles.end}>
<Text style={styles.text}>{item.text}</Text>
<Text style={styles.time}>{item.time}</Text>
</View>
<Text style={styles.content}>{item.content}</Text>
</View>
</View>
</TouchableOpacity>
);
}
return Element;
};
}
return (
<View style={{ flex: 1 }}>
<FlatList
extraData={Object}
data={Object}
renderItem={renderItem}
/>
</View>
);
}
Object.ts
export const Object = [
{
id: 1,
text: 'testtesttest',
content: 'testtesttest'
read: false
},
{
id: 2,
text: 'testtesttest',
content: 'testtesttest'
read: false
}
id: 3,
text: 'testtesttest',
content: 'testtesttest'
read: false
}
]
We can add inline styles into the component style props along with static styles,
For Example:
<TouchableOpacity onPress={readState}>
<View style={[styles.row, { backgroundColor: item.read ? '#FBFBFB' : 'FFF5E7' }]}>
<View style={styles.container}>
<View style={styles.end}>
<Text style={styles.text}>{item.text}</Text>
<Text style={styles.time}>{item.time}</Text>
</View>
<Text style={styles.content}>{item.content}</Text>
</View>
</View>
</TouchableOpacity>
Problem in your readState function and if (state[0].read) {. You always change item with index 0 and then check state[0].read for all elements of your array.

How to render a partial view on another view in react native

When I tried alert("Hi") in renderMoreView function, it actually works, but to display the View is the problem I am facing
export default class Home extends Component {
state = {
moreButton: false,
};
renderMoreView = () => {
return (
<View style={{flex: 1, height: 50, width: 50}}>
<Text>Hi</Text>
</View>
);
};
render () {
return (
<View>
.....
<TouchableOpacity
underlayColor="transparent"
onPress={() => this.setState ({moreButton: true})}
>
<Feather name="more-vertical" size={25} />
</TouchableOpacity>
...
{this.state.moreButton ? this.renderMoreView () : null}
</View>
);
}
}
This is what I am trying to do]
If I understand your question right, you could use Modal component. https://facebook.github.io/react-native/docs/modal
This can be done using modal. But if you want to do it more simply, install and use the module. react-native-awesome-alerts
$ npm i react-native-awesome-alerts --save
Example
import React from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
import AwesomeAlert from 'react-native-awesome-alerts';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { showAlert: false };
};
showAlert = () => {
this.setState({
showAlert: true
});
};
hideAlert = () => {
this.setState({
showAlert: false
});
};
render() {
const {showAlert} = this.state;
return (
<View style={styles.container}>
<Text>I'm AwesomeAlert</Text>
<TouchableOpacity onPress={() => {
this.showAlert();
}}>
<View style={styles.button}>
<Text style={styles.text}>Try me!</Text>
</View>
</TouchableOpacity>
<AwesomeAlert
show={showAlert}
showProgress={false}
title="AwesomeAlert"
message="I have a message for you!"
closeOnTouchOutside={true}
closeOnHardwareBackPress={false}
showCancelButton={true}
showConfirmButton={true}
cancelText="No, cancel"
confirmText="Yes, delete it"
confirmButtonColor="#DD6B55"
onCancelPressed={() => {
this.hideAlert();
}}
onConfirmPressed={() => {
this.hideAlert();
}}
/>
</View>
);
};
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff',
},
button: {
margin: 10,
paddingHorizontal: 10,
paddingVertical: 7,
borderRadius: 5,
backgroundColor: "#AEDEF4",
},
text: {
color: '#fff',
fontSize: 15
}
});

How to get user id from firebase in react native?

I need your help I'm using firebase for my app. I'm trying to get the users ID not the logged users no all users I have. I want to show their (uid) simply like in an alert for each user. Also, I'm showing them in a flatlist and when I set item.uid in an alert it shows (undefined). But, all the other data of the user is shown correctly. This what I did until now:
**
users.js
**
export default class usersList extends React.Component{
state = {
loading: false,
uid: '',
users: [],
items: []
};
componentDidMount() {
let itemsRef = f.database().ref('users').once('value').then(snapshot => {
var data = snapshot.val();
var items = Object.values(data);
this.setState({items});
console.log(snapshot.val())
});
}
renderItem({item}) {
return (
<View key={index} style={{width: '100%', overflow:'hidden', marginBottom: 5, justifyContent:'space-between', borderBottomWidth:1, borderColor: 'grey'}}>
<View>
<View style={{padding:5, width:'100%', flexDirection: 'row', justifyContent: 'space-between'}}>
<Text>{item.email}</Text>
</View>
</View>
</View>
)
}
render() {
return (
<View style={styles.container}>
<ScrollView>
{
this.state.items.length > 0
? <ItemComponent items={this.state.items} navigation={this.props.navigation} />
: <Text>No stores</Text>
}
</ScrollView>
</View>
);
}
}
//ItemComponent.js
export default class ItemComponent extends Component {
static propTypes = {
items: PropTypes.array.isRequired
};
render() {
return (
<View style={styles.itemsList}>
{this.props.items.map((item, index) => {
return (
<View key={index}>
<TouchableOpacity
onPress={ () => alert(item.uid)}>
<Text style={styles.itemtext}>{item.email}</Text>
</TouchableOpacity>
</View>
)
})}
</View>
);
}
}
firebase.database().ref('user').on('value', (datasnapshot) => {
this.setState({
_id: datasnapshot.key
});`
This solution worked for me
<Text style={styles.yourStyleHere}>UID: {auth.currentUser?.uid} </Text>

React-native flatlist not rendering?

My ReactNative FlatList is not rendering with this simple implementation.
<FlatList style={{flex:1, backgroundColor:'red'}}
data = {this.state.users}
keyExtractor={item => item.key.toString()}
renderItem={({item}) => {
return (
<ChatUserCard key={item.uid} username={item.username} />
)
}}
/>
ChatUserCard
<View style={styles.cardStyle}>
<Text style={styles.itemStyle}>{this.props.username}</Text>
<Button style={styles.buttonStyle}
title='Chat'
onPress={this.startChat} />
</View>
Try add comments to the view below the flatlist and remove flex 1 from the styles on the flatlist. Try that to check if it is related with the styles
I'm thinking what's going on is that you've not wrapped your FlatList in a View that has flex: 1 set. Also, you can probably use your uid as your key, rather than setting a key in your object data
Demo
https://snack.expo.io/#anonymoussb/so53688423
import * as React from 'react';
import { Text, View, StyleSheet, Button, FlatList } from 'react-native';
class ChatUserCard extends React.Component {
render() {
return (
<View style={styles.cardStyle}>
<Text style={styles.itemStyle}>{this.props.username}</Text>
<Button style={styles.buttonStyle}
title='Chat'
onPress={this.startChat} />
</View>
)
}
}
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
users: [
{ key: 123, uid: 123, username: 'taco' },
{ key: 456, uid: 456, username: 'cat' }
]
}
}
render() {
return (
<View style={styles.container}>
<FlatList style={{flex:1, backgroundColor:'red'}}
data = {this.state.users}
keyExtractor={item => item.key.toString()}
renderItem={({item}) => {
return (
<ChatUserCard key={item.uid} username={item.username} />
)
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
});

React Native pass index

I am making a music app using react-native-track-player. I made 3 components called Clusters, Songlist and Play.
How screen works
Clusters component -> Songlist component -> Play component. Problem for me is that I don't know how to pass the index of the song selected to the SongList component from Clusters component which will also allow me to pass it to my Play component. I am not sure how to do it.
I created data. First screen shows title and mood(Songlist component). Second screen (Songlist shows the playlist depending on the title that I clicked.
This is my where I get my data in another file
const ClusterData = [
{
title: "Cluster1",
data: [
{ name: "passionate" },
{ name: "rousing" },
{ name: "confident" },
{ name: "boisterous" },
{ name: "rowdy" }
],
songlist: [
{
id: "2222",
url: "http://tegos.kz/new/mp3_full/Post_Malone_-_Better_Now.mp3",
title: "Better Now",
artist: "Post Malone"
},
{
id: "2",
url:
"http://tegos.kz/new/mp3_full/5_Seconds_Of_Summer_-_Youngblood.mp3",
title: "YoungBlood",
artist: "5SOS"
}
]
},
{
title: "Cluster2",
data: [
{ name: "rollicking" },
{ name: "cheerful" },
{ name: "fun" },
{ name: "sweet" },
{ name: "amiable" },
{ name: "natured" }
],
songlist: [
{
id: "1111",
url:
"http://tegos.kz/new/mp3_full/Yellow_Claw_and_San_Holo_-_Summertime.mp3",
title: "Summertime",
artist: "Yellow Claw"
},
{
id: "1",
url:
"http://tegos.kz/new/mp3_full/Luis_Fonsi_feat._Daddy_Yankee_-_Despacito.mp3",
title: "Despacito",
artist: "Luis Fonsi"
}
]
}
];
This is my Clusters screen (first screen)
export default class Clusters extends Component {
render() {
return (
<View style={styles.container}>
<SectionList
renderItem={({ item, index }) => {
return (
<SectionListItem item={item} index={index}>
{" "}
</SectionListItem>
);
}}
renderSectionHeader={({ section }) => {
return <SectionHeader section={section} />;
}}
sections={ClusterData}
keyExtractor={(item, index) => item.name}
/>
</View>
);
}
}
class SectionHeader extends Component {
render() {
return (
<View style={styles.header}>
<Text style={styles.headertext}>{this.props.section.title}</Text>
<TouchableOpacity
onPress={() => Actions.SongList({ section: this.props.section })}
>
<Text style={styles.Play}> Play</Text>
</TouchableOpacity>
</View>
);
}
}
class SectionListItem extends Component {
render() {
return (
<View>
<Text style={styles.moodname}>{this.props.item.name}</Text>
</View>
);
}
}
This is my SongList screen (second screen)
export default class App extends Component {
render() {
return (
<View>
<FlatList
data={this.props.section.songlist}
renderItem={({ item, index, rowId }) => {
return <FlatListItem item={item} index={index} />;
}}
/>
</View>
);
}
}
class FlatListItem extends Component {
render() {
return (
<View>
<TouchableOpacity
onPress={() =>
Actions.Play({
songlist: this.props.item.songlist,
item: this.props.item
})
}
>
<Text style={styles.itemTitle}>{this.props.item.songtitle}</Text>
<Text style={styles.itemArtist}>{this.props.item.artist}</Text>
</TouchableOpacity>
</View>
);
}
}
This is my Play screen
import TrackPlayer from "react-native-track-player";
export default class Play extends Component {
componentDidMount() {
TrackPlayer.setupPlayer().then(async () => {
// Adds a track to the queue
await TrackPlayer.add(this.props.item.songlist[index]);
// Starts playing it
TrackPlayer.play();
});
}
onPressPlay = () => {
TrackPlayer.play();
};
onPressPause = () => {
TrackPlayer.pause();
};
render() {
return (
<View style={styles.container}>
<View style={{ flexDirection: "column" }}>
<TouchableOpacity style={styles.play} onPress={this.onPressPlay}>
<Text
style={{
fontWeight: "bold",
textAlign: "center",
color: "white"
}}
>
Play
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.pause} onPress={this.onPressPause}>
<Text
style={{
fontWeight: "bold",
textAlign: "center",
color: "white"
}}
>
Pause
</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
export default class App extends Component {
setSong(var selectedSong){
// do something with the selectedsong, maybe in the state
this.setState({currentSong: selectedSong});
}
render() {
return (
<View>
<FlatList
data={this.props.section.songlist}
renderItem={({ item, index, rowId }) => {
return <FlatListItem item={item} index={index} />;
}}
/>
</View>
);
}
}
You need something like this
export default class App extends Component {
this.state = {
index:0
}
setSong(var selectedSong){
var index = this.props.songlist.index(selectedSong);
this.setState({index: index});
}
render() {
return (
<View>
<FlatList
data={this.props.section.songlist}
renderItem={({ item, index, rowId }) => {
return <FlatListItem item={item} index={index} />;
}}
/>
</View>
);
}
}
class FlatListItem extends Component {
this.state = {
index:0
}
setSong(var selectedSong){
var index = this.props.songlist.index(selectedSong);
this.setState({index: index});
}
render() {
return (
<View>
<TouchableOpacity
onPress={() =>
Actions.Play({
songlist: this.props.item.songlist,
item: this.props.item,
index: this.state.index,
setSong: () => this.setSong
})
}
>
<Text style={styles.itemTitle}>{this.props.item.songtitle}</Text>
<Text style={styles.itemArtist}>{this.props.item.artist}</Text>
</TouchableOpacity>
</View>
);
}
}
just try passing a function as a prop that you can call in the child
function setSong(var selectedSong){
// do something with the selectedsong, maybe in the state
this.setState({currentSong: selectedSong});
}
and then pass this function
<TouchableOpacity
onPress={() =>
Actions.Play({
songlist: this.props.item.songlist,
item: this.props.item,
setSong: () => this.setSong
})
}
>

Categories

Resources