So I'm using this custom component progress steps from this github library:
https://github.com/colbymillerdev/react-native-progress-steps/tree/master and my code looks like this:
<View style={styles.container}>
<ProgressSteps >
<ProgressStep label="authentication " nextBtnDisabled={true} >
<Authentication />
</ProgressStep>
<ProgressStep label="Confirmation">
<View style={{ alignItems: 'center' }}>
<Text>good job !</Text>
</View>
</ProgressStep>
</ProgressSteps>
</View>
so there is only two screen, the first where you enter your user name and password,in this step i called a fetch api, so if the infos are correct it should lead you to the next step of confirmation.
and that's what i'm trying to do. the code of (Authentication/) is:
.....
<Button style={styles} color='#FFC617' title='log in' onPress={this.Autho} />
........
Autho = () => {
console.log(this.state)
fetch(....)
.then((response) => response.json())
.then((res) => {
if ("user_context" in res) {
AsyncStorage.setItem('user',res.user);
*what should i write here*
}
else {
alert("Error");
}
})
.done();
}
this is the method rendered every time you click the connect button log in i already tested it and it works fine but i want it to lead me to the next step.
as you can see i had nextBtnDisabled={true} so you can't go to the next step without login in.
i hope i detailed enough for you to understand and i really appreciate your response.thank you!
Related
i'm handling firebase auth errors and i cant show error message on screen
here is my code;
if (error.code === "auth/user-not-found") {
return (
<View>
<Text>user not found</Text>
<Text>try create a account or check ur mail and passwrd</Text>
</View>
)
}
but i use alert it works perfectly.
how can i solve it ?
Try to add some styles in your components so you can see something.
if (error.code === "auth/user-not-found") {
return (
<View style={{flex: 1, width: "100%", height: "100%", backgroundColor: "#f00"}}>
<Text>user not found</Text>
<Text>try create a account or check ur mail and passwrd</Text>
</View>
)
}
I like to try first with full width and height, and with a very basic color (in this case red) so I can watch whats happening in my views. Remember that you can save and metro gonna refresh your app in your emulator/phone.
I'm trying to make a custom loading screen while my Firebase function is updating the data and avoid the user to leave the screen while loading, except that my header is still clickable and doesn't prevent the user to go back.
I tried with SafeAeraView, etc. but I didn't get any result.
The research goal illustrated:
Here is a pic of what i mean
This is how I do it:
if (taked === true) {
setTimeout(() => {
cancelDelivery();
}, 1500);
return (
<SafeAreaView style={{ flex: 1, backgroundColor: "grey",justifyContent: "center", alignItems: "center"}}>
<View style={styles.mainContainer}>
<Image style={{width: 50, height: 50}} source={require('../../assets/images/delivraide-icon-192.png')}/>
<Text style={styles.patientText}>Veuillez patientez s'il vous plaƮt</Text>
</View>
</SafeAreaView>
);
After the function is executed, the user is returned to the parent with the PopToTop function.
Basically what you need to do is prevent default behavior while you are updating data by adding a listener on beforeRemove event (please check this doc to know when this event is triggered). You will need to have some state variable (updatingData or whatever) and set it to true when you start the request and set it to false when request completes.
navigation.addListener('beforeRemove', (e) => {
if (updatingData) {
e.preventDefault();
}
}
I am trying to change a button background color when clicked and toggle between list of buttons within the same button list. I ahve been trying this since yesterday and stuck at point where i am not able to proceed further.
More details - I have a page with questions and multiple option for the question and use should only select either of the answer YES/No/NA and that button background should be changed to different color, it works for a single question but for multiple questions i am not understanding which unique value to use to toggle the button color with in the same question.
I have created a snack for it here is an URL - https://snack.expo.io/#jerrypatels/bossy-bagel for some reason the snack is not working as expected on web but works well with mobile view, so request you to try the mobile version.
Now if i click first question YES it changes the color of all questions to YES.
Image how it is working
How i need it to look like
The state checked is on your AlongsideScreen component, not on each individual set of buttons as you probably intended. You probably want to split up the list of questions, list of buttons and everything like that into their own separate components to make managing the state easier, and you might want to consider using class components. Also, when you run into a problem, try simplifying the problem to allow you to understand it easier. You have a lot of extra code in your example that isn't related to the problem that I'm just going to replace with ... for now.
By breaking it up, the error becomes obvious:
const AlongsideScreen = ({ navigation }) => {
const [along, setAlong] = useState();
const [checked, setChecked] = useState();
return (
// ... other view code here
<View style={styles.containerText}>
// We pass in our questions as a prop to QuestionsList.
<QuestionsList questions={Questions}> </QuestionsList>
</View>
);
};
const QuestionsList = (props) => {
return (
<FlatList
data={props.questions}
keyExtractor={(item, index) => '' + index}
renderItem={({ item }) => (
<ButtonSelect item={item}></ButtonSelect>
)}
/>
)
}
const ButtonSelect = ({ item }) => {
return (
<FlatList
data={item.data}
keyExtractor={(item, index) => '2' + index}
renderItem={({ item, index }) => (
<View style={{ padding: 10 }}>
<Text style={[styles.text, { padding: 10 }]}>
{item.Q}
</Text>
<View style={styles.btnP}>
{item.options.map((list, ind) => {
return (
<SelectableButton item={item} list={list}></SelectableButton>
);
})}
</View>
</View>
)}
/>
)
}
const SelectableButton = ({ item, list }) => {
return (
<TouchableOpacity
style={[
styles.btn2,
{
width: width / item.length - item.width,
backgroundColor:
checked === list.id // ERROR! checked is undefined
? "red"
: '#F4F6FC',
},
]}
onPress={() => {
setChecked(list.id); // ERROR! setChecked is undefined!
}}>
<Text
style={[
Style.normalText,
{ textAlign: 'center' },
]}>
{list.value}
</Text>
</TouchableOpacity>
)
}
This is just your code, but it's been rearranged and the parts irrelevant to the issue have been deleted.
To fix the problem that you see above, you should add a prop for a listener for presses to SelectableButton and a prop for whether the button is checked. On the ButtonSelect, you should have a prop for a listener for when the currently selected button changes. Pass in whether the button is checked and a listener to each SelectableButton, and when that listener is called, call the listener prop. You may need to keep repeating this chain up, as there should only be a single source of truth. This is the "React Way".
Until expo lets me use Realm databases ive decided to go with Json and asyncstorage. The source data originates from Json anyway so for this app it makes sense to leave it as json.
I have a flatlist with the json displayed. To the left of each item in the list is a star icon.
When I touch each item in the list the star will go solid to indicate it has been pressed. Press it again, the icon will be an outline of a star to indicate it has been de-selected.
The onpress function looks like this symbols is the name of the JSON data the JSON data has 3 keys... symbol, name and iconName. Symbol is the item in the flatlist that is touched.
onPressListItem = ( symbol ) => {
for (var i = 0; i < this.state.symbols.length; i++){
if (this.state.symbols[i].symbol === symbol){
const copyOfSymbolsList = [...this.state.symbols];
if (copyOfSymbolsList[i].iconName === 'md-star') {
copyOfSymbolsList[i].iconName = 'md-star-outline';
} else {
copyOfSymbolsList[i].iconName = 'md-star';
}
this.setState({ symbols:copyOfSymbolsList });
}
}
}
So as you can see above it basically just scrolls through the entire json array to find the appropriate row and then makes a copy of the list, changes the data and then sets state again.
The app isn't super fast maybe half a second delay before the icon changes on my pixel 2 and there is only 100 records in the list. Im a little worried if the list gets into the thousands of rows itll be really bad.
Is there a better/faster/simpler/more react-y way to solve this problem?
EDIT
This is the renderListItem function which calls the onPress function
renderListItem = ({ item }) => {
return (
<TouchableOpacity
onPress={() => this.onPressListItem(item.symbol)}
>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{backgroundColor: 'powderblue'}}>
<Ionicons style={styles.listItemIcon} name={item.iconName} />
</View>
<View style={{backgroundColor: 'skyblue'}}>
<Text style={styles.listItem}>
{item.name.toUpperCase()} {item.symbol}
</Text>
</View>
</View>
</TouchableOpacity>
);
};
EDIT #2
This is the FlatList code.
<View style={styles.mainContainer}>
<FlatList
data={this.state.symbols}
keyExtractor= {(item, index) => item.symbol}
ItemSeparatorComponent={this.renderListSeparator}
renderItem={this.renderListItem}
/>
</View>
i guest your json structure is like this.
the_data = [
{'iconName': 'xxx', 'symbol': '<i class="fa fa-items"></i>'}
]
You can access this structure by index, passing the index to the onPressListItem function.
renderListItem = ({ item }, index) => {
return (
<TouchableOpacity
onPress={() => this.onPressListItem(index)}
>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{backgroundColor: 'powderblue'}}>
<Ionicons style={styles.listItemIcon} name={item.iconName} />
</View>
<View style={{backgroundColor: 'skyblue'}}>
<Text style={styles.listItem}>
{item.name.toUpperCase()} {item.symbol}
</Text>
</View>
</View>
</TouchableOpacity>
);
};
With this design you don't have to iterate your json.
onPressListItem = ( index ) => {
the_dataobj = the_data[index];
the_dataobj.iconName = 'md-start';
if (the_dataobj.iconName === 'md-start'){
the_dataobj.iconName = 'md-start_outline';
}
//you don't need a extra else here, is in-necesarry
the_data[index] = the_dataobj;
//set state ... do more
}
BTW: This is have nothing to do with react, the correct design of your workflow should be independent of the framework library.
Happy Codding!!!
For those of you reading, the accepted answer did not update the rendered list properly on screen. So the actual working code for me is below. Im pretty sure its because the accepted answer did not use the this.setState function to write the values back to the array.
Also the if then else needs to have an else in it because when the user taps the same row twice i want it to reverse its changes.
All that being said, the updates are still very slow. About the same speed as it was when using the for loop in the question. Not sure why.
onPressListItem = ( index ) => {
const copyOfSymbolsList = [...this.state.symbols];
thePressedSymbol = copyOfSymbolsList[index];
if (thePressedSymbol.iconName === 'md-star') {
thePressedSymbol.iconName = 'md-star-outline';
}else{
thePressedSymbol.iconName = 'md-star';
}
copyOfSymbolsList[index] = thePressedSymbol;
this.setState({ symbols:copyOfSymbolsList });
}
Im using react-native-qrcode-scanner from https://github.com/moaazsidat/react-native-qrcode-scanner and I read perfectly the code but when I go back to qr-scanner again it crashes.
I think it is because the camera is still working on background, there is a way to close it when it ends?
I believe you are having the same issue as this one on that github page.
And would recommend using that page to submit your problems regarding that software.
The following solution worked for navigation between Camera screen and others:
In Constructor:
this.state = {
focusedScreen: true
};
In render:
render() {
const { focusedScreen } = this.state;
if (!focusedScreen){
return <View />;
} else
{
return (
<QRCodeScanner ............
)
}
<QRCodeScanner
onRead={this.onSuccess.bind(this)}// change {this.onSuccess} to {this.onSuccess.bind(this)}
topContent={
<Text style={styles.centerText}>
Go to <Text style={styles.textBold}>wikipedia.org/wiki/QR_code</Text> on your computer and scan the QR code.
</Text>
}
bottomContent={
<TouchableOpacity style={styles.buttonTouchable}>
<Text style={styles.buttonText}>OK. Got it!</Text>
</TouchableOpacity>
}
/>