My current code is like this.
export default class All extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
checkedItems: new Map(),
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(id) {
this.setState((prevState) => ({ checkedItems: prevState.checkedItems.set(id, true) }));
console.log(this.state.checkedItems);
}
async componentDidMount() {
const items = ...;
this.setState({ items });
}
render() {
const { items } = this.state;
return (
<Container>
<Content>
<View>
{items.map((item) => (
<View key={item.id}>
<Text>{item.name}</Text>
<View>
<CheckBox
checked={this.state.checkedItems.get(item.id)}
onPress={() => this.handleChange(item.id)}
/>
</View>
</View>
))}
</View>
</Content>
</Container>
);
}
}
I would like to know how to uncheck.
Also, when I firstly check, console.log() in handleChange() outputs Map {}.
Is it correct?
Or if you know better way bay to use checkbox in map function, plz tell me.
I would appreciate it if you could give me advices.
I am trying to do firebase authentication using email and password for my expo app. On the login screen, if i press on the login button, it gives me the above message, " email address is badly formatted'.
The signup button should navigate to sign up page, but clicking on the button also gives me the same error.
export default class App extends React.Component{
constructor(props)
{ super(props);
this.state = { isLoadingComplete: false,
};
if (!firebase.apps.length){firebase.initializeApp(ApiKeys.FirebaseConfig );}
}
render()
{
if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {
return (
<AppLoading
startAsync={this._loadResourcesAsync}
onError={this._handleLoadingError}
onFinish={this._handleFinishLoading}
/>
);
} else {
return (
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
{Platform.OS === 'android' && <View style={styles.statusBarUnderlay} />}
{ <AppNavigator/> }
</View>
);
}
}
_loadResourcesAsync = async () => {
return Promise.all([
Asset.loadAsync([
require('./assets/images/robot-dev.png'),
require('./assets/images/robot-prod.png'),
]),
Font.loadAsync({
...Ionicons.font,
'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf'),
}),
]);
};
_handleLoadingError = error => {
console.warn(error);
};
_handleFinishLoading = () => {
this.setState({ isLoadingComplete: true });
};
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
statusBarUnderlay: {
height: 24,
backgroundColor: 'rgba(0,0,0,0.2)',
},
});
## login page
export default class LoginScreen extends React.Component {
constructor(props)
{
super(props);
this.state = {
email:' ' ,password:' ',
}
}
LoginButtonPress= (email, password) =>
{
try{
firebase.auth().signInWithEmailAndPassword(this.state.email.trim(), this.state.password)
.then(function(user){console.log(user)
})
}
catch(error){
Alert.alert(error.message);
}
}
render()
{
return (
<ScrollView style= {styles.container}>
<Container style ={styles.container}>
<Content>
<Form>
<Item floatingLabel>
<Label> Email Address</Label>
<Input autoCorrect = {false} autoCapitalize ="none"
onChangeText= {(email) => this.setState({email})}/>
</Item>
<Item floatingLabel>
<Label> Password</Label>
<Input secureTextEntry ={true}
autoCorrect = {false}
autoCapitalize = "none"
onChangetext = { (password)=> this.setState({password})}/>
</Item>
<Button success info onPress ={()=>this.LoginButtonPress(this.state.email, this.state.password)}>
<Text> LogIn </Text>
</Button>
<Button primary onPress = {()=> this.props.navigation.navigate('SignupScreen')}>
<Text> First Time User? SignUpNow </Text>
</Button>
<Button onPress ={()=> this.props.navigation.navigate('ResetPassScreen')}>
<Text> Forgot Password? Reset Now </Text>
</Button>
</Form>
</Content>
</Container>
</ScrollView>
);
}}
##signup page
export default class SignupScreen extends React.Component{
constructor(props)
{
super(props);
this.state = { email: '',
password:''
}
}
SignUpButtonPress= (email, password)=>
{
try {
firebase.auth().createUserWithEmailAndPassword(this.state.email.trim(), this.state.password)
}
catch(error){
Alert.alert(error.message);
}
}
render ()
{
return (
<ScrollView>
<Container style = {styles.container}>
<Content>
<Form>
<Item floatingLabel>
<Label> Email Address</Label>
<Input autoCapitalize = "none" autoCorrect ={false} emailonChangeText ={(email)=>this.setState({email})} />
</Item>
<Item floatingLabel>
<Label> Password</Label>
<Input secureTextEntry = {true} onChangeText ={(password)=>this.setState({password})} />
</Item>
<Button success info onPress = {this.SignUpButtonPress(this.state.email, this.state.password)}>
<Text> SignUp </Text>
</Button>
</Form>
</Content>
</Container>
</ScrollView>
);
}
Your onPress for the signup button is immediately calling the SignupButtonPress callback on every render. Change
// notice that `onPress` is directly calling `this.SignUpButtonPress`
<Button success info onPress = {this.SignUpButtonPress(this.state.email, this.state.password)}>
To
<Button success info onPress = {() => {this.SignUpButtonPress(this.state.email, this.state.password);}}>
I'm EXTREMELY new at coding, and I took Grinder's course on React Native. I have no idea how to save the datepickerios date object into Firebase. I'm pretty sure something in this code here is incorrect.
Any help would be greatly appreciated. Also, if anyone's looking for a mentee, I'd be grateful for your help. Thanks!
class ScoreForm extends Component {
constructor(props) {
super(props);
this.state = {chosenDate: new Date()};
this.setDate = this.setDate.bind(this);
}
setDate(newDate) {
this.setState({chosenDate: newDate});
}
render() {
return (
<View>
<CardSection>
<Text style={styles.pickerTextStyle}>Enter Date</Text>
</CardSection>
<CardSection>
{/* <Input
label="Date"
placeholder="MM/DD/YY"
value={this.props.date}
onChangeText={value => this.props.scoreUpdate({ prop: 'date', value })}
/> */}
<DatePickerIOS
style={{ flex: 1 }}
mode='date'
date={this.state.chosenDate}
onDateChange={value => this.props.scoreUpdate({ prop: 'date', value })}
/>
</CardSection>
<CardSection>
<Input
label="Score"
placeholder="Add Number"
value={this.props.score}
onChangeText={value => this.props.scoreUpdate({ prop: 'score', value })}
/>
</CardSection>
</View>
);
}
}
const styles = {
pickerTextStyle: {
fontSize: 18,
paddingLeft: 20
}
};
const mapStateToProps = (state) => {
const { date, score } = state.scoreForm;
return { date, score };
};
export default connect(null, { scoreUpdate }) (ScoreForm);
Since I am using Redux, I'm assuming I that I don't want to store it in state, correct? Here is the this.props.ScoreUpdate action:
export const scoreUpdate = ({ prop, value }) => {
return {
type: SCORE_UPDATE,
payload: { prop, value }
};
};
I need to call SearchScreen class method from a React Navigation Header.
The Navigator look like this:
Search: {
screen: SearchScreen,
path: 'search/:query',
navigationOptions: {
title: 'Search',
header: {
right: (
<MaterialCommunityIcons
name="filter"
onPress={() => {
console.log(this);
}}
style={{marginRight: 15, color: 'white'}}
size={24}
/>
),
},
}
}
I've made it work by doing:
// declare static navigationOptions in the Component
static navigationOptions = {
title: 'Title',
header: ({ state }) => ({
right: (
<MaterialCommunityIcons
name="filter"
onPress={state.params.handleFilterPress}
style={{marginRight: 15, color: 'white'}}
size={24}
/>
),
}),
}
_handleFilterPress() {
// do something
}
componentDidMount() {
// set handler method with setParams
this.props.navigation.setParams({
handleFilterPress: this._handleFilterPress.bind(this)
});
}
I've resolved the issue the following way:
static navigationOptions = ({ navigation }) => {
return {
headerRight: () => (
<TouchableOpacity
onPress={navigation.getParam('onPressSyncButton')}>
<Text>Sync</Text>
</TouchableOpacity>
),
};
};
componentDidMount() {
this.props.navigation.setParams({ onPressSyncButton: this._onPressSyncButton });
}
_onPressSyncButton = () => {
console.log("function called");
}
Hooks solution with FunctionComponent, useState and useEffect
Ref the official docs (https://reactnavigation.org/docs/en/header-buttons.html#header-interaction-with-its-screen-component) it is done by:
class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: <LogoTitle />,
headerRight: (
<Button
onPress={navigation.getParam('increaseCount')}
title="+1"
color="#fff"
/>
),
};
};
componentDidMount() {
this.props.navigation.setParams({ increaseCount: this._increaseCount });
}
state = {
count: 0,
};
_increaseCount = () => {
this.setState({ count: this.state.count + 1 });
};
/* later in the render function we display the count */
}
However I could not get this to work when working with the hooks api. My state variables were always undefined, but after I thought about how the hooks api is implemented it all made sense, so the solution was to update the navigation param every time a significant state variable was changed:
const [count, setCount] = useState(0);
useEffect(() => {
props.navigation.setParams({ increaseCount });
}, [count]);
const increaseCount = () => setCount(count + 1);
I came across same issue and able to resolve the issue from below links.
class MyScreen extends React.Component {
static navigationOptions = {
header: {
right: <Button title={"Save"} onPress={() => this.saveDetails()} />
}
};
saveDetails() {
alert('Save Details');
}
render() {
return (
<View />
);
}
}
Source: react-native issues 145
Below is my code
import React, { Component } from "react";
import {
Container,
Header,
Item,
Input,
Icon,
Button,
Text,
Left,
Body,
Right,
Content,
Spinner,
List,
ListItem
} from "native-base";
import { View, Image, StyleSheet, Keyboard } from "react-native";
import { connect } from "react-redux";
import {
onClear,
onSearchTextChanged,
searchForProfiles
} from "../../actions/searchActions";
class SearchBar extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Header searchBar rounded>
<Button
iconLeft
style={{ paddingLeft: 0 }}
light
onPress={this.props.onBackPress}
>
<Icon style={{ marginLeft: 0, fontSize: 35 }} name="arrow-back" />
</Button>
<Item>
<Icon name="ios-search" />
<Input
placeholder="Search"
onChangeText={this.props.onChangeText}
value={this.props.searchText}
/>
<Button small transparent onPress={this.props.onClear}>
<Icon name="ios-close" />
</Button>
</Item>
<Button transparent onPress={this.props.onSearch}>
<Text>Search</Text>
</Button>
</Header>
);
}
}
class SearchWorld extends Component {
static navigationOptions = ({ navigation }) => ({
left: null,
header: () => {
const { state } = navigation;
return (
<SearchBar
onBackPress={() => navigation.goBack()}
onChangeText={text => {
state.params.onChangeText(text);
}}
onSearch={state.params.onSearch}
onClear={state.params.onClear}
searchText={state.params.searchText}
/>
);
}
});
onChangeText = text => {
this.props.navigation.setParams({
...this.props.navigation.state,
searchText: text
});
this.props.onSearchTextChanged(text);
};
onSearch = () => {
Keyboard.dismiss();
const profile = { search: "test" };
const token = this.props.token;
this.props.searchForProfiles(token, profile);
};
onClear = () => {
this.props.onClear();
this.props.navigation.setParams({
...this.props.navigation.state,
searchText: ""
});
};
componentDidMount() {
this.props.navigation.setParams({
onChangeText: this.onChangeText,
onSearch: this.onSearch,
onClear: this.onClear,
searchText: this.props.searchText
});
}
render() {
const { searchResults } = this.props;
let items = [];
if(searchResults && searchResults.data && searchResults.data.length > 0) {
items = [...searchResults.data];
}
return this.props.loading ? (
<Container style={{ alignItems: "center", justifyContent: "center" }}>
<Spinner color="#FE6320" />
</Container>
) : (
<Container>
<Content>
<List
style={{}}
dataArray={items}
renderRow={item => (
<ListItem style={{ marginLeft: 0}}>
<Text style={{paddingLeft: 10}}>{item.password}</Text>
</ListItem>
)}
/>
</Content>
</Container>
);
}
}
const mapStateToProps = state => {
const { token } = state.user;
const { searchText, searchResults, error, loading } = state.searchReaducer;
return {
token,
searchText,
searchResults,
error,
loading
};
};
export default connect(mapStateToProps, {
onClear,
onSearchTextChanged,
searchForProfiles
})(SearchWorld);
static navigationOptions = ({navigation}) => {
return {
headerTitle: () => <HeaderTitle />,
headerRight: () => (<Button iconLeft transparent small onPress = {navigation.getParam('onPressSyncButton')}>
<Icon style ={{color:'white', fontWeight:'bold'}} name='md-save' size = {32} />
<Text style ={{color:'white', fontWeight:'bold'}}>save</Text>
</Button>),
headerTintColor:'black',
headerStyle: {
backgroundColor: '#6200EE'
},
}
};
this.props.navigation.setParams({ onPressSyncButton: this.updateUserProfile });
I am trying to simply pass props between views in my React-Native app. Namely, I am trying to collect data from a text input, and pass it to the next view in a string. This is what I have:
first view:
constructor(props) {
super(props);
this.state = {name: "", email: "" };
}
_pressRow(){
let name=this.state.name;
let email=this.state.email;
this.props.navigator.push({
ident: "ImportContactScreen",
sceneConfig: Navigator.SceneConfigs.FloatFromRight,
passProps: { name: name}
});
}
<TextInput
style={styles.input}
ref= "name"
onChangeText={(name) => this.setState({name})}
value={this.state.name}
/>
<F8Button
style={styles.button}
onPress={() => this._pressRow()}
caption="Continue"
/>
second view:
props = {name}
<Text style={styles.h1}>Hi, {this.props.name}. Let`'`s import your contacts:</Text>
The navigator I'm using looks like:
class MyAppNavigator extends React.Component{
constructor(props) {
super(props);
}
render() {
return (
<Navigator
ref="appNavigator"
initialRoute={this.props.initialRoute}
renderScene={this._renderScene}
configureScene={(route) => ({
...route.sceneConfig || Navigator.SceneConfigs.FloatFromRight
})}
/>
);
}
_renderScene(route, navigator) {
var globalNavigatorProps = { navigator }
switch (route.ident) {
case "LoginScreen":
return <LoginScreen {...globalNavigatorProps} />
case "UserFlowScreen":
return <UserFlowScreen {...globalNavigatorProps} />
case "ImportContactScreen":
return <ImportContactScreen {...globalNavigatorProps} />
default:
return <LoginScreen {...globalNavigatorProps} />
}
}
};
module.exports = MyAppNavigator;
When I run this, this.props.name comes up blank
passProps is a property of route. Try adding {...route.passProps} to each return in your switch statement:
return <LoginScreen {...globalNavigatorProps} {...route.passProps} />