I want to disable the setState message warning
On the layout 1 :
My constructor :
constructor(props){
super(props);
//Constructeur
this.lestachesitemsRef=getDatabase().ref('n0rhl66bifuq3rejl6118k8ppo/lestaches'); this.lestachesitems=[];
this.state={
//Debutdustate
lestachesSource: new ListView.DataSource({rowHasChanged: (row1, row2)=>row1 !== row2}),
Prenom: '',
Nom: '',}
}
My function :
ajouter= () => {
if( (this.state.Nom !== '') && (this.state.Prenom !== '')) { this.lestachesitemsRef.push({ Nom: this.state.Nom , Prenom: this.state.Prenom , }); this.setState({ Nom : '' }) , this.setState({ Prenom : '' }) }
}
My componentDidMount
componentDidMount()
{
//DidMount
this.lestachesitemsRef.on('child_added', (dataSnapshot)=>{ this.lestachesitems.push({id: dataSnapshot.key, text: dataSnapshot.val()}); this.setState({lestachesSource: this.state.lestachesSource.cloneWithRows(this.lestachesitems)}); });
this.lestachesitemsRef.on('child_removed', (dataSnapshot)=>{ this.lestachesitems = this.lestachesitems.filter((x)=>x.id !== dataSnapshot.key); this.setState({ lestachesSource: this.state.lestachesSource.cloneWithRows(this.lestachesitems)});});
}
My vue :
<TextInput style={styles.Dtext} placeholder="Nom" onChangeText={(text) => this.setState({Nom: text})} value={this.state.Nom}/>
<TextInput style={styles.Dtext} placeholder="Prenom" onChangeText={(text) => this.setState({Prenom: text})} value={this.state.Prenom}/>
<Button title='Allerlayout2' onPress={() => this.verl2()} onLongPress={() => this.infol2()} buttonStyle={ styles.View } icon={{name: 'squirrel', type: 'octicon', buttonStyle: styles.View }} />
<Button title='ajouter' onPress={() => this.ajouter()} onLongPress={() => this.infoajout()} buttonStyle={ styles.View } icon={{name: 'squirrel', type: 'octicon', buttonStyle: styles.View }} />
<ListView dataSource={this.state.lestachesSource} renderRow={this.renderRowlestaches.bind(this)} enableEmptySections={true} />
The Layout2 the same thing as Layout1.
Thank you !
Warnings
Warnings will be displayed on screen with a yellow background. These alerts are known as YellowBoxes. Click on the alerts to show more information or to dismiss them.
As with a RedBox, you can use console.warn() to trigger a YellowBox.
YellowBoxes can be disabled during development by using console.disableYellowBox = true;. Specific warnings can be ignored programmatically by setting an array of prefixes that should be ignored: console.ignoredYellowBox = ['Warning: ...'];.
In CI/Xcode, YellowBoxes can also be disabled by setting the IS_TESTING environment variable.
http://facebook.github.io/react-native/docs/debugging.html#yellowbox-redbox
Related
I have created a register page and I am trying hook up a loading ticker while I create the user account.
I am running into an issue where mapStateToProps() is being executed whenever the screen loads meaning that any values I have being mapped error as the state is undefined. None of my reducers or actions are executing to cause mapStateToProps() to run. Have I set something within my screen to cause this to execute, I completely understand that my state is indeed undefined but why does mapStateToProps even run in the initial load?
.......
interface State {
name: string,
email: string;
mobileNo: string;
password: string;
passwordConf: string;
nameTouched: boolean;
emailTouched: boolean;
mobileNoTouched: boolean;
passwordTouched: boolean;
passwordConfTouched: boolean;
loading: boolean;
}
class RegisterScreen extends React.Component<{
navigation: any;
register: Function}, State> {
emailInputRef = React.createRef<FormTextInput>();
mobileNoInputRef = React.createRef<FormTextInput>();
passwordInputRef = React.createRef<FormTextInput>();
passwordConfInputRef = React.createRef<FormTextInput>();
readonly state: State = {
name: "",
email: "",
password: "",
mobileNo:"",
passwordConf: "",
emailTouched: false,
passwordTouched: false,
nameTouched: false,
mobileNoTouched: false,
passwordConfTouched: false,
loading: false
};
handleNameChange = (name: string) => {
this.setState({ name: name });
};
handleEmailChange = (email: string) => {
this.setState({ email: email });
};
handleMobileNoChange = (mobileNo: string) => {
this.setState({ mobileNo: mobileNo });
};
handlePasswordChange = (password: string) => {
this.setState({ password: password });
};
handlePasswordConfChange = (passwordConf: string) => {
this.setState({ passwordConf: passwordConf });
};
handleNameSubmitPress = () => {
if (this.emailInputRef.current) {
this.emailInputRef.current.focus();
}
};
handleEmailSubmitPress = () => {
if (this.mobileNoInputRef.current) {
this.mobileNoInputRef.current.focus();
}
};
handleMobileNoSubmitPress = () => {
if (this.passwordInputRef.current) {
this.passwordInputRef.current.focus();
}
};
handlePasswordSubmitPress = () => {
if (this.passwordConfInputRef.current) {
this.passwordConfInputRef.current.focus();
}
};
handleNameBlur = () => {
this.setState({ nameTouched: true });
};
handleEmailBlur = () => {
this.setState({ emailTouched: true });
};
handleMobileNoBlur = () => {
this.setState({ mobileNoTouched: true });
};
handlePasswordBlur = () => {
this.setState({ passwordTouched: true });
};
handlePasswordConfBlur = () => {
this.setState({ passwordConfTouched: true });
};
render() {
const {
name,
email,
password,
mobileNo,
passwordConf,
emailTouched,
passwordTouched,
nameTouched,
mobileNoTouched,
passwordConfTouched,
} = this.state;
const nameError =
!name && nameTouched
? strings.NAME_REQUIRED
: undefined;
const emailError =
!email && emailTouched
? strings.EMAIL_REQUIRED
: undefined;
const mobileError =
!mobileNo && mobileNoTouched
? strings.MOBILE_REQUIRED
: undefined;
const passwordError =
!password && passwordTouched
? strings.PASSWORD_REQUIRED
: undefined;
const passwordConfError =
!passwordConf && passwordConfTouched && (password === passwordConf)
? strings.PASSWORD_CONF_REQUIRED
: undefined;
return (
<KeyboardAvoidingView
style={styles.container}
behavior="padding"
>
<Image source={imagePath} style={styles.logo} />
<View style={styles.form}>
{/* Name */}
<FormTextInput
keyboardType={"default"}
value={this.state.name}
onChangeText={this.handleNameChange}
onSubmitEditing={this.handleNameSubmitPress}
placeholder={strings.NAME_PLACEHOLDER}
autoCorrect={false}
returnKeyType="next"
onBlur={this.handleNameBlur}
error={nameError}
/>
{/* Email */}
<FormTextInput
keyboardType={"email-address"}
ref={this.emailInputRef}
value={this.state.email}
onChangeText={this.handleEmailChange}
onSubmitEditing={this.handleEmailSubmitPress}
placeholder={strings.EMAIL_PLACEHOLDER}
autoCorrect={false}
returnKeyType="next"
onBlur={this.handleEmailBlur}
error={emailError}
/>
{/* MobileNo */}
<FormTextInput
keyboardType={"numeric"}
ref={this.mobileNoInputRef}
value={this.state.mobileNo}
onChangeText={this.handleMobileNoChange}
onSubmitEditing={this.handleMobileNoSubmitPress}
placeholder={strings.MOBILE_PLACEHOLDER}
autoCorrect={false}
returnKeyType="next"
onBlur={this.handleMobileNoBlur}
error={mobileError}
/>
{/* Password */}
<FormTextInput
keyboardType={"default"}
ref={this.passwordInputRef}
value={this.state.password}
onChangeText={this.handlePasswordChange}
onSubmitEditing={this.handlePasswordSubmitPress}
placeholder={strings.PASSWORD_PLACEHOLDER}
secureTextEntry={true}
returnKeyType="done"
onBlur={this.handlePasswordBlur}
error={passwordError}
/>
{/* Password Conf */}
<FormTextInput
keyboardType={"default"}
ref={this.passwordConfInputRef}
value={this.state.passwordConf}
onChangeText={this.handlePasswordConfChange}
placeholder={strings.PASSWORD_CONF_PLACEHOLDER}
secureTextEntry={true}
returnKeyType="done"
onBlur={this.handlePasswordConfBlur}
error={passwordConfError}
/>
<ActivityIndicator animating={true} />
<Button
title="Register"
onPress={() => this.props.register(
name,
email,
mobileNo,
password)}
disabled={!email || !password || !name || !password || !passwordConf}
/>
</View>
</KeyboardAvoidingView>
);
}
}
const mapStateToProps = (state) => {
console.log(this.state);
//On screen load this executes with state = undefined, not sure what's causing it to fire
return {
loading : state.creatingUser
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({register: register}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(RegisterScreen);
React Redux tries to improve performance by doing shallow equality reference checks on incoming props in shouldComponentUpdate but you need to remember that
shouldComponentUpdate method is not called for the initial render therfore mapStateToProps will run in the initial load
my problem is quite simple but I'm new to react native dev. I'd like to save multiple elements with AsyncStorage (I'm using react-native-simple-store
a library that works like a wrapper but it's same logic) I want display all items for a key in a list , my code look like this:
constructor(props) {
super(props)
this.state = {
UserInput: "",
}
}
SaveValue = () => {
store.push('Favorites', this.state.UserInput)
Keyboard.dismiss()
};
FetchValue = () => {
store.get('Favorites').then((value) => {
this.setState({
favs: value
});
}).done();
};
Same thing with AsynStorage, it just update the item which is not my goal, I'd like to add a new one
SaveValue = () => {
AsyncStorage.setItem("Favorites", this.state.UserInput);
Keyboard.dismiss()
};
FetchValue = () => {
AsyncStorage.getItem("Favorites").then((value) => {
this.setState({
favs: value
});
}).done();
};
This part is my view where I try to display data, you can also see that I use a text input and two buttons one to save and the other to display an array of items stored
render() {
return (
<View>
<TextInput
onChangeText={(UserInput) => this.setState({UserInput})}
placeholder= "Type something"
value={this.state.UserInput} />
<TouchableOpacity
onPress={this.SaveValue}>
<Text>Save</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.FetchValue}>
<Text>Fetch</Text>
</TouchableOpacity>
<Text>{this.state.favs}</Text>
</View>
);
}
At this point I can see only one item, I tried to figure it out and saw that I have to use another method called push but when I changed save by push it throw me an error
Unhandled Promise Rejection : Existing value for key "Favorites" must be of type null or array, revived string.
Thanks!
it will work :)
renderFavorites = () => {
AsyncStorage.getItem("Favorites").then((favs) => {
favs.map((fav) => {
return (<Text> {fav} </Text>);
});
});
}
render() {
return (
<View>
<TextInput
onChangeText={(UserInput) => this.setState({UserInput})}
placeholder= "Type something"
value={this.state.UserInput} />
<TouchableOpacity
onPress={this.SaveValue}>
<Text>Save</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.FetchValue}>
<Text>Fetch</Text>
</TouchableOpacity>
{this.renderFavorites()}
</View>
);
}
Solution using JSON:
SaveValue = () => {
const newFavs = [...this.state.favs, this.state.UserInput];
this.setState({ favs: newFavs, UserInput: '' }, () => {
AsyncStorage.setItem("Favorites", JSON.stringify(this.state.favs));
Keyboard.dismiss()
});
};
FetchValue = () => {
AsyncStorage.getItem("Favorites").then((value) => {
this.setState({
favs: JSON.parse(value)
});
}).done();
};
I know was a thousand such questions relating to this same issue, but I've already exhausted ideas what might cause it in my case :/
I'm trying to update variable when after getting response from API.
I already changed all functions to use arrow function but I keep getting this error:
this.setState is not a function
and I can't find error in my code.
Can anyone see what's wrong?
app/routes/users/login/view.js
const UsersLoginView = (props) => {
let email = '';
this.state = {
textError: '',
inputError: false,
}
login = (event) => {
device_info = {
UUID: DeviceInfo.getUniqueID(),
brand: DeviceInfo.getBrand(),
model: DeviceInfo.getModel(),
system: DeviceInfo.getSystemName(),
system_version: DeviceInfo.getSystemVersion(),
timezone: DeviceInfo.getTimezone(),
locale: DeviceInfo.getDeviceLocale(),
}
fetch("my url", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: email,
device: device_info
})
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
textError: 'SUCCESS',
inputError: false
});
})
.catch(error => {
this.setState({
textError: error.message,
inputError: true
});
})
.done();
},
updateEmail = (text) => {
email = text
}
return (
<Container>
<Content>
<Text style={{fontWeight: 'bold'}}>
User
</Text>
<Form>
<Item error={this.state.inputError}>
<Icon active name='ios-at-outline' />
<Input
autoCorrect={false}
placeholder='E-mail'
returnKeyType='go'
keyboardType='email-address'
autoCapitalize='none'
onChangeText = { (text) => updateEmail(text) }
/>
</Item>
<Text>{this.state.textError}</Text>
<Button full light style={{marginTop: 20}} onPress={ () => login }>
<Text>Login</Text>
</Button>
</Form>
</Content>
</Container>
);
};
export default UsersLoginView;
app/routes/users/login/index.js
import UsersLoginView from './view';
class UsersLogin extends Component {
constructor(props) {
super(props);
}
render() {
return (
<UsersLoginView />
);
}
}
export default UsersLogin;
maybe login function should be in index.js file then I will have access to state ?
The error is here: const UsersLoginView = (props) => {, you need to use a class if you want to maintain state.
What I am trying to do:
I am trying to have a page where you can search for particular items, this then sends a request to the API which returns back a set of values based on this search.
Currently, I am using a Listview which does not show until the user has put in their search term and clicked ok. Which once the user has clicked search, the list view is then updated with the reply.
What is happening:
When the user clicks searches, I get the following error:
Undefined is not an object (evaluating dataSource.rowIdentities)
Here is the code so far:
class Search extends Component {
constructor(props) {
super(props);
this.state = {
term: '',
showResults: false,
isSearch: false,
SearchResults: ''
}
this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
SearchResults: this.ds.cloneWithRows(["Row 1", "Row 2"]),
};
}
onSearchButtonPress() {
this.setState({isSearch: true});
}
_renderCategoryIcon() {
}
_renderSearchResults(item) {
return (
<Text>Hello world</Text>
)
}
render() {
if(this.state.isSearch)
{
return (
<ViewContainer>
<StatusBarBackground style={{backgroundColor: "#009fe3"}} navigator={this.props.navigator} />
<SearchBar
placeholder='Search'
onChangeText={(text)=> this.setState({term: text})}
onSearchButtonPress={this.onSearchButtonPress.bind(this)}
/>
<ListView
style={styles.containerView}
enableEmptySections={true}
horizontal={false}
initialListSize={10}
dataSource={this.state.SeachResults}
automaticallyAdjustContentInsets={false}
renderRow={(item) => { return this._renderSearchResults(item) }} />
</ViewContainer>
);
}else{
return (
<ViewContainer>
<StatusBarBackground style={{backgroundColor: "#009fe3"}} navigator={this.props.navigator} />
<SearchBar
placeholder='Search'
onChangeText={(text)=> this.setState({term: text})}
onSearchButtonPress={this.onSearchButtonPress.bind(this)}
/>
</ViewContainer>
)
}
}
}
const styles = StyleSheet.create({
title: {
fontSize:30,
},
});
You have set your default SearchResults as an empty string. Use an empty array instead:
this.state = {
term: '',
showResults: false,
isSearch: false,
SearchResults: this.ds.cloneWithRows([])
}
The React Native TextInput component doesn't support the onSubmitEditing event if it specified as a multi-line input.
Is there a way to detect when the user presses the enter/submit/send (depending on which keyboard layout is specified) button after entering some text?
I realize this is an old post, but I stumbled here from Google and wanted to share my solution. Because of some things that needed to happen in the case of submit, vs simply blurring, I wasn't able to use onBlur to interpret submit.
I utilized an onKeyPress listener to track the Enter key, and then proceeded with the submit. (Note, this is currently only supported in iOS until this PR is merged.)
// handler
onKeyPress = ({ nativeEvent }) => {
if (nativeEvent.key === 'Enter') {
// submit code
}
};
// component
<TextInput
autoFocus={true}
blurOnSubmit={true}
enablesReturnKeyAutomatically={true}
multiline={true}
onChangeText={this.onChangeText}
onKeyPress={this.onKeyPress}
returnKeyType='done'
value={this.props.name}
/>
Note, the blurOnSubmit is still required to prevent the return key from being passed to your onChangeText handler.
On iOS this should work according to the documentation.
Use the onBlur function:
Callback that is called when the text input is blurred
In combination with the ios only blurOnSubmit:
If true, the text field will blur when submitted. The default value is
true for single-line fields and false for multiline fields. Note that
for multiline fields, setting blurOnSubmit to true means that pressing
return will blur the field and trigger the onSubmitEditing event
instead of inserting a newline into the field.
I'll try testing this.
Edit:
Done testing
blurOnSubmit doesn't work like it's supposed to in react-native 0.14.2. Even when set to true, the return/done button and enter key just create a newline and do not blur the field.
I'm not able to test this on newer versions at the moment.
Try it! It works in the middle of the line also!
<TextInput
placeholder={I18n.t('enterContactQuery')}
value={this.state.query}
onChangeText={text => this.setState({ query: text, allowEditing: true })}
selection = {this.state.selection}
onSelectionChange={(event) => this.setState({ cursorPosition: event.nativeEvent.selection, selection: event.nativeEvent.selection, allowEditing: true })}
onSubmitEditing={() => {
const { query, cursorPosition } = this.state;
let newText = query;
const ar = newText.split('');
ar.splice(cursorPosition.start, 0, '\n');
newText = ar.join('');
if (cursorPosition.start === query.length && query.endsWith('\n')) {
this.setState({ query: newText });
} else if (this.state.allowEditing) {
this.setState({
query: newText,
selection: {
start: cursorPosition.start + 1,
end: cursorPosition.end + 1
},
allowEditing: !this.state.allowEditing
});
}
}}
multiline = {true}
numberOfLines = {10}
blurOnSubmit={false}
editable={true}
// clearButtonMode="while-editing"
/>
constructor(props) {
super(props);
this.state = {
query: '',
cursorPosition: [0,0],
selection: null,
allowEditing: true
}
}
constructor () {
super()
this.state = {
text : '',
lastText : '',
inputHeight:40
}
}
writing(text){
this.setState({
text : text
})
}
contentSizeChange(event){
if(this.state.lastText.split("\n").length != this.state.text.split("\n").length){
this.submitTextInput();
}else{
this.setState({
inputHeight : event.nativeEvent.contentSize.height
})
}
}
submitTextInput(){
Alert.alert('submit input : ' + this.state.text);
this.setState({
text : ''
})
}
render() {
return (
<View style={{flex:1,backgroundColor:'#fff'}}>
<TextInput
style={{height:this.state.inputHeight}}
multiline={true}
onChangeText={(text) => this.writing(text)}
onContentSizeChange={(event) => this.contentSizeChange(event)}
onSubmitEditing={() => this.submitTextInput()}
value={this.state.text}
/>
</View>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>