I am trying to have a button cross out text with 'line-through'. I am not sure how to connect this to the button.
'''
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default function App() {
const [name, setName] = useState('shaun')
const clickHandler = () => {
setName('shaun (CROSSED OUT)');
}
return (
<View style={styles.container}>
<Text>My name is {name}</Text>
<Text></Text>
<View style={styles.buttonContainer}>
<Button title='update state' onPress={clickHandler} />
</View>
</View>
);
}
You can use a state variable to keep track of it.
quick example -
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default function App() {
const [name, setName] = useState('shaun')
const [crossedOut, setCrossedOut] = useState(false) // extra state variable
const clickHandler = () => {
setName('shaun (CROSSED OUT)');
setCrossedOut(true) // set it to true on click
}
return (
<View style={styles.container}>
{/* apply style only if crossedOut is true */}
<Text style={crossedOut && {textDecorationLine: 'line-through'}}>My name is {name}</Text>
<View style={styles.buttonContainer}>
<Button title='update state' onPress={clickHandler} />
</View>
</View>
);
}
Related
I'm new and need to use useState but how do I bind the button in a separate component and the Text in another component?
components 1
const Bottom = () => {
const [counter, setCounter] = useState(0);
function number() {
setCounter(counter + 1);
}
console.log(counter);
components 1
<View style={styles.seperator}>
<TouchableOpacity style={styles.button} onPress={number}>
<Text style={styles.buttonText}>Save</Text>
</TouchableOpacity>
</View>
components 2
<Text style={styles.number}>{props.counter}</Text>
My full code
import React, {useState, useEffect} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import styles from './Header.styles';
const Header = props => {
return (
<View style={styles.container}>
<View style={styles.headContainer}>
<Text style={styles.title}>TODO..</Text>
<Text style={styles.number}>{props.counter}</Text>
</View>
</View>
);
};
export default Header;
import React, {useState} from 'react';
import {
View,
Text,
Stylesheet,
TouchableOpacity,
TextInput,
} from 'react-native';
import {Header} from 'react-native/Libraries/NewAppScreen';
import styles from './Bottom.styles';
const Bottom = () => {
const [counter, setCounter] = useState(0);
function number() {
setCounter(counter + 1);
}
console.log(counter);
return (
<View style={styles.bottomContainer}>
<TextInput
style={styles.input}
placeholder="Todo"
onChangeText={text => setText(text)}></TextInput>
<View style={styles.seperator}>
<TouchableOpacity style={styles.button} onPress={number}>
<Text style={styles.buttonText}>SAVE</Text>
</TouchableOpacity>
</View>
</View>
);
};
export default Bottom;
The code has 2 components, I want the number to increase when I press the button
i uploaded all my code sorry if it's a bad question i'm new
I tried to import props and pages
What i understand is that you try to achieve this
const component1 = ({state1,setState1})=>{return()}
const component2 = ({state2,setState2})=>{return()}
then in your screen
const HomeScreen = () =>{
const [yourState1,setYourState1]= useState(someValue1);
const [yourState2,setYourState2]= useState(someValue2);
return(
<View>
<Component1 state1={yourstate1} setState1={yourSetstate1} />
<Component2 state2={yourstate2} setState1={yourSetstate2} />
</View>
)
}
Component1 can be your button, Component2 can be your Text Component
This way you can manipulate your state.
While pressing RoundButton component nothing happens, but when I press press return it works,
Here is my custom Button component
Custom Button:
import React from 'react';
import { Text, View, StyleSheet, TouchableOpacity, } from 'react-native';
export const RoundedButton = ({
style = {},
textStyle = {},
size = 125,
...props
}) => {
return( <TouchableOpacity style={[styles(size).radius,style]}>
<Text style={[styles(size).text,textStyle]}>{props.title} </Text>
</TouchableOpacity>);
};
Calling from component:
import React, {useState} from 'react';
import { Text, View, StyleSheet,TouchableHighlight } from 'react-native';
import {TextInput} from "react-native-paper";
import {RoundedButton} from '../../components/RoundedButton'
export const Focus = ({addSubject}) => {
const [focusSubject, setFocusSubject] = useState(null);
const [tempItem, setTempItem] = useState(null);
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text>Want something?</Text>
<View styles={styles.inputContainer} >
<TextInput onSubmitEditing={({ nativeEvent }) => {
setTempItem(nativeEvent.text);
addSubject(nativeEvent.text)
}} />
<RoundedButton size={100} title="+" onPress={()=> {addSubject(tempItem)}} />
</View>
</View>
</View>
);
}
You need to call onPress on TouchableOpacity
Custom Button:
import React from 'react';
import { Text, View, StyleSheet, TouchableOpacity, } from 'react-native';
export const RoundedButton = ({
style = {},
textStyle = {},
size = 125,
...props
}) => {
return(
<TouchableOpacity onPress={props.onButtonHandler} style={[styles(size).radius,style]}>
<Text style={[styles(size).text,textStyle]}>{props.title} </Text>
</TouchableOpacity>
)};
In your component pass onButtonHandler
Calling from component:
import React, {useState} from 'react';
import { Text, View, StyleSheet,TouchableHighlight } from 'react-native';
import {TextInput} from "react-native-paper";
import {RoundedButton} from '../../components/RoundedButton'
export const Focus = ({addSubject}) => {
const [focusSubject, setFocusSubject] = useState(null);
const [tempItem, setTempItem] = useState(null);
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text>Want something?</Text>
<View styles={styles.inputContainer} >
<TextInput onSubmitEditing={({ nativeEvent }) => {
setTempItem(nativeEvent.text);
addSubject(nativeEvent.text)
}} />
<RoundedButton size={100} title="+" onButtonHandler={()=> {addSubject(tempItem)}} />
</View>
</View>
</View>
);
}
I have tried to open Modal from another component in react-native, but modal is not open. so please help me if have any solution. this is my code
modal.js
import React from './node_modules/react';
import { View, Text } from 'react-native';
const ProfileModal = () => {
return (
<View>
<Text>HELLO TEXT</Text>
</View>
);
}
export default ProfileModal;
----------------------------------------
header.js
import ProfileModal from './ProfileModal';
import { Image, View, TouchableOpacity, Text } from 'react-native';
import Modal from 'react-native-modal';
const openLoginPopup = () => {
return (
<TouchableOpacity onPress={() => this.openModal}>
<Text> Login </Text>
</TouchableOpacity>
)
}
const openModal = () => {
return (
<Modal isVisible={true}>
<ProfileModal />
</Modal>
)
}
Thanks,
In that case, react-native-modal provide callback onBackdropPress, onBackButtonPress to close.
You can use it like this:
const ProfileModal = ({ open, onClose }) => {
return (
<Modal isVisible={open} onBackButtonPress={onClose} onBackdropPress={onClose}>
<View>
<Text>HELLO TEXT</Text>{' '}
</View>
</Modal>
)
}
Then pass onClose function when using it:
<ProfileModal open={open} onClose={()=> setOpen(false)} />
It's like you write the content modal in modal file. So you can do it something like:
modal.js
import React, {useState} from 'react';
import { View, Text } from 'react-native';
const ProfileModal = () => {
return (
<View>
<Text>HELLO TEXT</Text>
</View>
);
}
export default ProfileModal;
----------------------------------------
header.js
import ProfileModal from './ProfileModal';
import { Image, View, TouchableOpacity, Text } from 'react-native';
import Modal from 'react-native-modal';
const Header = () => {
const [open, setOpen] = useState(false)
return (
<View>
{/* some content */}
{/* btn trigger */}
<TouchableOpacity onPress={() => setOpen(true)}>
<Text> Login </Text>
</TouchableOpacity>
<Modal isVisible={open}>
<ProfileModal />
</Modal>
</View>
)
}
or
modal.js
import React, {useState} from 'react';
import { View, Text } from 'react-native';
const ProfileModal = ({ open }) => {
return (
<Modal isVisible={open}>
<View>
<Text>HELLO TEXT</Text>
</View>
</Modal>
);
}
export default ProfileModal;
----------------------------------------
header.js
import ProfileModal from './ProfileModal';
import { Image, View, TouchableOpacity, Text } from 'react-native';
import Modal from 'react-native-modal';
const Header = () => {
const [open, setOpen] = useState(false)
return (
<View>
{/* some content */}
{/* btn trigger */}
<TouchableOpacity onPress={() => setOpen(true)}>
<Text> Login </Text>
</TouchableOpacity>
<ProfileModal open={open} />
</View>
)
}
First of all openModal method is not part of openLoginPopup so remove this before openModal method.
Just use directly like below,
const openLoginPopup = () => {
return (
<TouchableOpacity onPress={openModal}>
<Text> Login </Text>
</TouchableOpacity>
)
}
Second issue was that you also don't need arrow function in onPress event until you want to pass some parameters in openModal method. You can directly pass the method name and it will work.
I noticed when I would try to type anything in the text input field it would automatically delete it. I have narrowed down to the problem being the value field and commenting it out allows me to input text but I am not sure what could be the issue.
import React, { useState } from 'react';
import { StyleSheet, Text, View, TextInput, Button } from 'react-native';
export default function App() {
const [enteredGoal, setEnteredGoal] = useState('');
const goalInputHandler = (enteredText) => {
setEnteredGoal(enteredGoal);
};
const addGoalHandler = () => {
console.log(enteredGoal);
};
return (
<View style={styles.screen}>
<View style={styles.inputContainer}>
<TextInput
placeholder="Course Goal"
style={styles.input}
onChangeText={goalInputHandler}
value={enteredGoal}
/>
<Button title='Add' onPress={addGoalHandler} />
</View>
<View />
</View>
);
}
Two reasons:
variables in goalInputHandler() do not match. Passing in enteredText but trying to use enteredGoal.
goalInputHandler() does not return anything. You need to use parenthesis instead of curly braces, or add a return statement before setEnteredGoal().
Correct code:
import React, { useState } from 'react';
import { StyleSheet, Text, View, TextInput, Button } from 'react-native';
export default function App() {
const [enteredGoal, setEnteredGoal] = useState('');
const goalInputHandler = (enteredText) => (
setEnteredGoal(enteredText);
);
const addGoalHandler = () => (
console.log(enteredGoal);
);
return (
<View style={styles.screen}>
<View style={styles.inputContainer}>
<TextInput
placeholder="Course Goal"
style={styles.input}
onChangeText={goalInputHandler}
value={enteredGoal}
/>
<Button title='Add' onPress={addGoalHandler} />
</View>
<View />
</View>
);
}
My function onPressreturn undefined is not a object
This is my code :
import React, {Component} from 'react';
import {Image, Platform, StatusBar, ListView, TouchableHighlight} from 'react-native';
import {connect} from 'react-redux';
import {Actions} from 'react-native-router-flux';
import {
Container,
Content,
Text,
Icon,
View,
Left,
Right,
Header,
Body,
Title,
Animated
} from 'native-base';
import styles from './styles';
class Championnat extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
{slug : 'team', name : 'Liqgue1'},
{slug : 'worldcup', name : 'Coupe du monde'},
]),
};
}
pressRow(data) {
console.log(data);
}
renderRow(data){
return (
<TouchableHighlight onPress={()=> this.pressRow(data)}>
<View style={styles.lstView}>
<Image style={styles.lstPicto} />
<Text style={styles.lstText}>{data.name}</Text>
<Icon name="angle-right" right style={styles.lstIcon} />
</View>
</TouchableHighlight>
)
}
render() {
return (
<Container style={styles.container}>
<Header style={styles.header}>
<Left>
<Button transparent onPress={() => Actions.pop()}>
<Icon active name="angle-left"/>
</Button>
</Left>
<Body>
<Title>Choisir un championnat</Title>
</Body>
<Right></Right>
</Header>
<View style={{flex: 1}}>
<ListView
dataSource={this.state.dataSource}
renderRow = {this.renderRow.bind(this)}
></ListView>
</View>
</Container>
)
}
}
export default connect()(Championnat);
Inside of your constructor you need to bind() your function, or use arrow functions.
constructor() {
// your code
this.pressRow = this.pressRow.bind(this);
}
Otherwise, declare your function as an arrow function.
pressRow = (data) => {
// your code
}
change renderRow(data) as arrow function like below snippet
renderRow = (data) => {
// your logic
}
and make sure you pressRow function should be arrow function
pressRow = (data) => {
console.log(data);
}
Hope this will work. :)
This is my screen when i tape on TouchableHighlight. The pb exist only on TouchableHighlight if i change TouchableHighlight for Button, there is no pb.
But on offical doc (https://facebook.github.io/react-native/docs/listview.html), react ask to use TouchableHighlight on listView
try this one.. it should work.. when you render a listView, each of you data belong to one unique ID..
pressRow(event) {
console.log(event);
}
renderRow(data, rowID){
return (
<TouchableHighlight key={rowID} onPress={()=> this.pressRow(rowID)}>
<View style={styles.lstView}>
<Image style={styles.lstPicto} />
<Text style={styles.lstText}>{data.name}</Text>
<Icon name="angle-right" right style={styles.lstIcon} />
</View>
</TouchableHighlight>
)
}
This is my entire code :
In renderRow, if i comment Button an decomment TouchableHighlight it doesn't work, if i comment TouchableHighlight and decomment Button, it'work's.
import React, {Component} from 'react';
import {Image, Platform, StatusBar, ListView, TouchableHighlight} from 'react-native';
import {connect} from 'react-redux';
import {Actions} from 'react-native-router-flux';
import {
Container,
Content,
Text,
Item,
Input,
Button,
Icon,
View,
Left,
Right,
Header,
Body,
Title,
Spinner,
Animated
} from 'native-base';
import styles from './styles';
import * as competition from '../../../services/competition';
class ContentLoaded extends Component {
render() {
return (
<Text>Hello {this.props.name}!</Text>
);
}
}
class Competition extends Component {
constructor(props) {
super(props);
this.pressRow = this.pressRow.bind(this);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
this.fetchData();
}
/**
* Cherche les competitions
*/
fetchData = function() {
competition.getAll()
.then((data) => {
console.log(data);
this.setState({
dataSource: this.state.dataSource.cloneWithRows(data),
loaded: true,
});
})
.catch((exception) => {
console.log('competition controller 47', exception);
});
}
/**
* Click sur une competiotn
* #param data
*/
pressRow = (data, rowId) => {
console.log(data);
console.log(rowId);
}
/**
* render d'une ligne
* #param data
* #returns {XML}
*/
renderRow(data, rowId){
return (
//<TouchableHighlight key={rowID} style={styles.lstView} onPress={()=> this.pressRow(rowId)}>
<Button style={styles.lstView} onPress={()=> this.pressRow(data, rowId)}>
<Image style={styles.lstPicto} />
<Text style={styles.lstText}>{data.name}</Text>
<Icon name="angle-right" right style={styles.lstIcon} />
</Button>
//</TouchableHighlight>
)
}
/**
* Affichage conditionnek
* #returns {XML}
* #constructor
*/
ContentLoaded () {
if (!this.state.loaded) {
return <Text>
Loading movies...
</Text>
}
return <ListView
dataSource={this.state.dataSource}
renderRow = {this.renderRow.bind(this)}
></ListView>
}
/**
* Render
* #returns {XML}
*/
render() {
return (
<Container style={styles.container}>
<Header style={styles.header}>
<Left>
<Button transparent onPress={() => Actions.pop()}>
<Icon active name="angle-left"/>
</Button>
</Left>
<Body>
<Title>Choisir un championnat</Title>
</Body>
<Right></Right>
</Header>
<View style={{flex: 1}}>
{!this.state.loaded ? (
<Spinner size="small" color="#000000" />
) : (
<ListView
dataSource={this.state.dataSource}
renderRow = {this.renderRow.bind(this)}
></ListView>
)}
</View>
</Container>
)
}
}
export default connect()(Competition);
import React, {Component} from 'react';
import {Image, Platform, StatusBar, ListView, TouchableHighlight} from 'react-native';
import {connect} from 'react-redux';
import {Actions} from 'react-native-router-flux';
import {
Container,
Content,
Text,
Icon,
View,
Left,
Right,
Header,
Body,
Title,
Animated
} from 'native-base';
import styles from './styles';
class Championnat extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
{slug : 'team', name : 'Liqgue1'},
{slug : 'worldcup', name : 'Coupe du monde'},
]),
};
}
pressRow(data) {
console.log(data);
}
renderRow(data){
return (
<TouchableHighlight onPress={()=> this.pressRow(data)}>
<View style={styles.lstView}>
<Image style={styles.lstPicto} />
<Text style={styles.lstText}>{data.name}</Text>
<Icon name="angle-right" right style={styles.lstIcon} />
</View>
</TouchableHighlight>
)
}
render() {
return (
<Container style={styles.container}>
<Header style={styles.header}>
<Left>
<Button transparent onPress={() => Actions.pop()}>
<Icon active name="angle-left"/>
</Button>
</Left>
<Body>
<Title>Choisir un championnat</Title>
</Body>
<Right></Right>
</Header>
<View style={{flex: 1}}>
<ListView
dataSource={this.state.dataSource}
renderRow = {this.renderRow.bind(this)}
></ListView>
</View>
</Container>
)
}
}
export default connect()(Championnat);