onChangeText setState only sets one character not the whole string - react-native

I accept text input from a search bar and setState to text but its only one character at a time how can I continue to update and add to the state rather than replace what's in state? I feel like this is the intended action but my code does not do this.
class FindRecipesScreen extends Component {
static navigationOptions = {
title: "Find Recipes",
header: null
};
constructor(props) {
super(props);
this.state = {
search: "",
recipe: "",
text: "",
};
}
backToHomePage = () => {
this.props.navigation.navigate("Home");
};
componentDidMount() {
this.props.getRecipeList(this.props.auth.jwt);
}
handleSearch = text => {
console.log("text", text);
this.setState({text: text});
};
render() {
return (
<View style={styles.recipe}>
<View style={styles.recipeBar}>
<ActionNavbar title="Find Recipes"
leftAction={this.backToHomePage}
leftIcon={require("app/assets/icons/cancel.png")}
rightAction={this.backToHomePage}
rightIcon={require("app/assets/icons/filter.png")}/>
</View>
<View>
<View>
<SearchBar
containerStyle={styles.searchContainer}
inputContainerStyle={styles.searchInputContainer}
inputStyle={styles.searchInput}
lightTheme
searchIcon={searchIcon}
round
onChangeText={this.handleSearch}
placeholder="Search Cookbooks"
/>
<View style={styles.forward}>
<Image
style={styles.forwardIcon}
width={18}
height={18}
source={require("app/assets/icons/forward.png")}
/>
</View>
</View>
</View>
</View>
);
}
}

I found the solution... I needed const { search } = this.state; after render but before return with searcher

Use debouncer in the handleSearch function so the state is set after your debounce time.

Related

How to pass state between screens in React Native

This is screen 1, where I am supposed to be passing the state for button text.
export class EditProfile extends Component {
constructor(props) {
super(props);
this.navigateToName = this.navigateToName.bind(this);
this.navigateToAboutMe = this.navigateToAboutMe.bind(this);
this.navigateToInterests = this.navigateToInterests.bind(this);
this.state = {
showing: true,
aboutUser: {
buttonText: "hey",
showing: false,
},
};
}
navigateToName = () => {
this.props.navigation.navigate("CreateProfile", {
showing: false,
});
};
navigateToAboutMe = () => {
this.props.navigation.navigate("AboutUser", {
aboutUser: this.state.aboutUser,
});
};
navigateToInterests = () => {
this.props.navigation.navigate("Interests", { showing: false });
};
render() {
return (
<View>
<View style={ProfileEditStyle.justifyImage}>
<Image
style={ProfileEditStyle.image}
source={require("../../Graphics/jessica_alba.jpg")}
/>
</View>
<View>
<Text style={ProfileEditStyle.basictext}>Basic Info</Text>
<TouchableOpacity style={ProfileEditStyle.buttons}>
<Text style={ProfileEditStyle.text} onPress={this.navigateToName}>
Edit Name
</Text>
</TouchableOpacity>
<TouchableOpacity style={ProfileEditStyle.buttons}>
<Text style={ProfileEditStyle.text}>Edit Photo</Text>
</TouchableOpacity>
<TouchableOpacity style={ProfileEditStyle.buttons}>
<Text style={ProfileEditStyle.text}>Edit Location</Text>
</TouchableOpacity>
<TouchableOpacity
style={ProfileEditStyle.buttons}
onPress={this.navigateToAboutMe}
>
<Text style={ProfileEditStyle.text}>Edit About Me</Text>
</TouchableOpacity>
<TouchableOpacity
style={ProfileEditStyle.buttons}
onPress={this.navigateToInterests}
>
<Text style={ProfileEditStyle.text}>Edit Interests</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
export default EditProfile;
This is screen 2, where I want the state for the buttonText to change on the continue button component.
export class AboutUser extends Component {
constructor(props) {
super(props);
this.navigatToInterests = this.navigatToInterests.bind(this);
this.checkEntry = this.checkEntry.bind(this);
var params = props.navigation.state.params.aboutUser;
this.state = {
value: "",
};
}
<ContinueButton
text={this.props.route.params.aboutUser.buttonText}
color="#ff304f"
style={CreateAboutMe.centerButton}
onPress={this.navigatToInterests}
/>
I am trying to do conditional rendering for the continue button component. When its on one screen I want it to say "continue" and when its on another route I want it to say " Save and Go Back". However when I try to change the state between screens for some reason I either get a params error or the state doesn't change.
Get parameter from previous screen :
constructor(){
const isShowBtn = this.props.navigation.getParam("showing");
this.state = {
value: isShowBtn
}
}

TextInput focus blurring when first clicked

There was no issue before I tried to implement the handleInputBlur and handleInputFocus functions (Used to change the background when in focus). When I first click on the TextInput it comes into focus, but then immediately blurs, resulting in the background flashing then disappearing. What's strange is that after this first click, the future clicks work absolutely fine, focusses and blurs as it should. I do not understand why on the initial click/focus it immediately blurs. Code below:
EDIT: Bit more context, it's inside of a modal, which contains multiple of these editable items.
class EditableItem extends Component {
constructor(props) {
super(props)
const { value } = this.props
this.state = {
value,
isFocused: null,
}
}
handleInputBlur = () => {
this.setState({ isFocused: false })
console.log('blurring')
}
handleInputFocus = () => {
this.setState({ isFocused: true })
console.log('focussing')
}
render() {
const { name, secure, children, autoCapitalize } = this.props
const { value, isFocused } = this.state
const multiline = !secure
return (
<View>
<View style={styles.container}>
<Text style={styles.name}>{name}</Text>
<View style={isFocused ? styles.activeBackground : styles.unfocusedBackground}>
<TextInput
placeholder={name}
placeholderTextColor={COLOR_BASE_3}
underlineColorAndroid="transparent"
style={styles.value}
secureTextEntry={secure}
value={value}
// blurOnSubmit
onSubmitEditing={() => {
Keyboard.dismiss()
}}
returnKeyType="done"
keyboardAppearance="dark"
autoCapitalize={autoCapitalize}
onChangeText={this.onChange}
multiline={multiline}
onBlur={() => this.handleInputBlur()}
onFocus={() => this.handleInputFocus()}
/>
{children}
</View>
</View>
<View style={styles.divider} />
</View>
)
}
onChange = value => {
const { onChange } = this.props
this.setState({ value })
onChange(value)
}
}
Ok so solved this by setting autofocus to true in the TextInput. Not sure why not having this set causes this issue but it's a solution regardless.

How do you use checkbox in map function in React Native?

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.

View inside curly braces not showing

I'm new in ReactNative. I'm following a tutorial from Udemy. I've been trying to show a value from a variable. its working in the instructor's video but not in my code. the code is given below:
export default class App extends React.Component {
state = {
placeName: '',
places: []
}
placeNameChangedHandler = val => {
this.setState({
placeName: val
})
}
placeSubmitHandler = () => {
if (this.state.placeName.trim() === "") {
return;
}
this.setState(prevState => {
return {
places: prevState.places.concat(prevState.placeName)
}
})
}
render() {
const placesOutput = this.state.places.map(place => {
<Text>{place}</Text>
})
return (
<View style={styles.container}>
<View style={styles.inputContainer}>
<TextInput
placeholder="Type something"
style={styles.placeInput}
value={this.state.placeName}
onChangeText={this.placeNameChangedHandler}/>
<Button
style={styles.placeButton}
onPress={this.placeSubmitHandler}
title="Add"/>
</View>
<View>
{this.placesOutput}
</View>
</View>
);
}
}
but the {placeOutput} is not showing anything. its working in the instructor's video but not in my code. What am I doing wrong?
You aren't returning anything in your map() function. Your render function should look like this:
render() {
const placesOutput = this.state.places.map(place => {
return <Text>{place}</Text> //Added return statement
})
return (
<View style={styles.container}>
<View style={styles.inputContainer}>
<TextInput
placeholder="Type something"
style={styles.placeInput}
value={this.state.placeName}
onChangeText={this.placeNameChangedHandler}/>
<Button
style={styles.placeButton}
onPress={this.placeSubmitHandler}
title="Add"/>
</View>
<View>
{this.placesOutput}
</View>
</View>
);
}
All I did was add a return statement in your this.state.places.map() function.

How would I disable a function by clicking on TextInput

I have this class for blinking text:
class BlinkerFluid extends React.Component {
constructor(props) {
super(props);
this.state = {
isShowingText: true,
TextInputName = ''
};
setInterval(() => {
this.setState(previousState => {
return { isShowingText: !previousState.isShowingText };
});
}, 700);
}
render () {
let display = this.state.isShowingText ? this.props.text : ' ';
return (
<Text style={styles.other}>{display}</Text>
);
}
}
And this class to render the blinking text:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { text: 'x' };
}
render() {
return (
<View style={styles.container}>
<Text style={styles.other}>$ root | > </Text>
<BlinkerFluid text=' _' />
<TextInput style={styles.lol}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
</View>
);
}
}
I want to be able to stop the blinking of the text when I click on the TextInput prop and/or write to it.
How would I go about doing that?
I've been trying to search for an answer on my own, read the docs, but nothing has helped.
Any help is appreciated!
You could try something like the below code snippet (I've only included the code for App. You can implement the paused functionality in the BlinkerFluid however you want.
Basically, I'm storing in the state whether the blinker should be paused or not, then passing that value through to the BlinkerFluid component as a prop. You can set the pauseBlinker state easily, perhaps on onChangeText as in the example, or on press of a TouchableOpacity element etc.
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
text: 'x',
pauseBlinker: false,
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.other}>$ root | > </Text>
<BlinkerFluid text=' _' paused={this.state.pauseBlinker} />
<TextInput style={styles.lol}
onChangeText={(text) => this.setState({ text, pauseBlinker: true, })}
value={this.state.text}
/>
</View>
);
}
}