<Search
ref="search_box"
onSearch={this.onSearch}
backgroundColor="white"
cancelButtonTextStyle={{ color: "red" }}
placeholder="Search Food..."
placeholderCollapsedMargin={wp("40%")}
placeholderExpandedMargin={wp("7%")}
searchIconCollapsedMargin={wp("45%")}
inputHeight={hp("4%")}
/>
<List>
<ListItem>
<Text>Milk</Text>
</ListItem>
<ListItem>
<Text>Chicken</Text>
</ListItem>
<ListItem>
<Text>Rice</Text>
</ListItem>
Hey everyone, I am using React Native with a class component and I was wondering how can I hide the list, and show it only when I tap on the search bar?
You can defined a boolean variable and set it true when search text input focused,
like that
...
this.state = {
showList: false,
}
...
return (
<View>
<SearchBar
...
onFocus={() => setState({showList: true})}
/>
{this.state.showList && (
<FlatList
...
/>
)}
</View>
)
here I supposed search component inherits the TextInput properties.
Related
I made 2 screens one home screen and 2nd edit screen I need to edit data of home screen from edit screen and save it and that data should also update in home and detail screen. How can I do this without redux or context. Can anyone tell me.
Home.js
class Home extends Component {
state = {
post: [
{
key: "1",
title: "A Good Boi",
des: "He's a good boi and every one know it.",
image: require("../assets/dog.jpg"),
},
],
};
render() {
return (
<FlatList
data={this.state.post}
renderItem={({ item }) => (
<>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => this.props.navigation.navigate("Edit", item)}
style={styles.Edit}
>
<MaterialCommunityIcons
name="playlist-edit"
color="green"
size={35}
/>
</TouchableOpacity>
<Card
title={item.title}
subTitle={item.des}
image={item.image}
onPress={() => this.props.navigation.navigate("Details", item)}
/>
</>
)}
/>
Edit.js
class ListDetails extends Component {
render() {
const listing = this.props.route.params;
return (
<View>
<Image style={styles.image} source={listing.image} />
<View style={styles.detailContainer}>
<AppTextInput value={listing.title} />
<AppTextInput value={listing.des} />
</View>
<AppButton
text="Save"
onPress={() => this.props.navigation.goBack("Home")}
/>
</View>
Details.js
const listing = this.props.route.params;
return (
<View>
<Image style={styles.image} source={listing.image} />
<View style={styles.detailContainer}>
<Text style={styles.title}>{listing.title}</Text>
<Text style={styles.des}>{listing.des}</Text>
</View>
</View>
);
You can pass a function from your home screen to setState for it in your edit screen. In case navigating to edit screen causes the home screen unmounted, you can change the navigate method to push of stack navigator (I haven't tested yet). The code now should look like:
HomeScreen.js:
onEdit=(data)=>{
setState(...);
}
...
<TouchableOpacity
activeOpacity={0.7}
onPress={() => this.props.navigation.navigate("Edit", {item, onEdit})} //use push instead if error occured
style={styles.Edit}
>
...
Edit.js
class ListDetails extends Component {
render() {
const {item:listing, onEdit} = this.props.route.params;
return (
<View>
<Image style={styles.image} source={listing.image} />
<View style={styles.detailContainer}>
<AppTextInput value={listing.title} />
<AppTextInput value={listing.des} />
</View>
<AppButton
text="Save"
onPress={() => { onEdit(...); this.props.navigation.goBack("Home");}}
/>
</View>
Whenever I activate the onPress method by tapping on a message, the MessageScreen component just re-renders rather than displaying ChatScreen. This happens even if I replace ChatScreen with any other screen. Any help on the matter is much appreciated.
App.js
<NavigationContainer ref={containerRef} initialState={initialNavigationState}>
<Drawer.Navigator>
<Drawer.Screen name="Feed" component={BottomTabNavigator} options={{swipeEnabled: false}} />
<Drawer.Screen name="Settings" component={SettingsStack} options={{swipeEnabled: false}} />
</Drawer.Navigator>
</NavigationContainer>
BottomTabNavigator
const BottomTab = createBottomTabNavigator();
export default function BottomTabNavigator({ navigation, route }) {
{...HomeStack Code}
{...ProfileStack Code}
const MyMessagesStack = createStackNavigator();
function MessagesStack() {
return (
<MyMessagesStack.Navigator initialRouteName={"Messages"}
screenOptions={{headerShown: false}}>
<MyMessagesStack.Screen name="Messages" component={MessagesScreen} />
<MyMessagesStack.Screen name="Chats" component={ChatScreen} />
</MyMessagesStack.Navigator>
);
}
return (
<BottomTab.Navigator initialRouteName={INITIAL_ROUTE_NAME} >
<BottomTab.Screen
name="Home"
component={HomeStack}
options={{title: 'Feed'}}
/>
<BottomTab.Screen
name="Messages"
component={MessagesStack}
options={{title: 'Messages'}}
/>
<BottomTab.Screen
name="Profile"
component={ProfileStack}
options={{title: 'Profile'}}
/>
</BottomTab.Navigator>
);
}
MessageScreen.js
//flatscreen to render message components
</View>
<FlatList
data={Data}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => props.navigation.navigate('Chats')} >
<Message
image={item.image}
name={item.name}
lastMessage={item.message}
timeStamp={item.timestamp}
opened
/>
</TouchableOpacity>
)}
/>
The reason your components are remounting is because there are components defined inside other components:
function BottomTabNavigator() {
// Here
function MessagesStack() {
// ...
}
// ...
}
You need to define them outside to avoid that:
function MessagesStack() {
// ...
}
function BottomTabNavigator() {
// ...
}
I am trying to make cards clickable and expandable, but when updating state, it occurs in all the cards . I just want to make the state change in only one card (the one on which the event occurred , in this case, a click event).
However, the state gets updated for every other cards. Currently this does work on one item but it needs to work on others too.
export default class TransactionCards extends React.Component {
constructor(props) {
super(props);
this.state = {
isHidden: true
};
}
toggleHidden() {
this.setState({
isHidden: !this.state.isHidden
});
}
renderCards() {
return this.props.data.map((card, index) => (
<View key={card.id}>
<View style={styles.dateContainer}>
<Text style={styles.dateText}>{card.time}</Text>
</View>
<Card>
<TouchableWithoutFeedback onPress={this.toggleHidden.bind(this)}>
<View>
<View>
<View style={styles.transactionContainer}>
<Image
style={styles.countryImage}
source={require("../../assets/images/us-country-icon.png")}
/>
<Text style={styles.transactionTitle}>{card.title}</Text>
<Text style={styles.transactionAmount}>{card.cost}</Text>
<Icon
name={card.transactionType == "debit" ? "log-out" : "log-in"}
type="feather"
color={card.transactionType == "debit" ? "red" : "green"}
size={18}
iconStyle={styles.transactionIcon}
/>
</View>
<View>
<Text style={styles.transactionBankDetails}>{card.bankDetails}</Text>
</View>
</View>
{/* Setting visiblity condition */}
{!this.state.isHidden && (
<View>
<Divider style={styles.CardItemDivider} />
<View display="flex" flexDirection="row" justifyContent="space-between">
<View>
<Text style={styles.transactionBankDetails}>
{card.transactionCategory}
</Text>
<Text style={styles.transactionBankDetails}>{card.accountName}</Text>
</View>
<View>
<Icon name="bell" type="feather" iconStyle={styles.transactionIcon} />
</View>
</View>
</View>
)}
</View>
</TouchableWithoutFeedback>
</Card>
</View>
));
}
render() {
return <ScrollView showsVerticalScrollIndicator={false}>{this.renderCards()}</ScrollView>;
}
}
Create a new component for card and pass required params
Do the toggleHidden function inside the Card component
then inside the file it should look like
<Card {SetYourPassedParams} />
......
You have two items connected to the same state value on the same state. If you want to separate the behaviours you have to separate the values too.
This question already has an answer here:
StackNavigator through Component gives undefined error
(1 answer)
Closed 4 years ago.
Currently I am trying to have a list view inside of a segmented control. I set up a segmented control in my main file, so that when the segment
main.js
{this.state.seg === 2 && (
<List
dataArray={datas}
renderRow={data =>
<ListItem
button
onPress={() => this.props.navigation.navigate(data.route)}
>
<Left>
<Text>
{data.text}
</Text>
</Left>
<Right>
<Icon name="arrow-forward" />
</Right>
</ListItem>
}
/>
)}
this works properly and navigates to a completely new page to the route that I want from navigate. However, if I try to separate it like this
ListView.js
class ListView extends Component {
render() {
return (
<List
dataArray={datas}
renderRow={data =>
<ListItem
button
onPress={() => this.props.navigation.navigate(data.route)}
>
<Left>
<Text>
{data.text}
</Text>
</Left>
<Right>
<Icon name="arrow-forward" />
</Right>
</ListItem>
}
/>
);
}
}
and main.js as
{this.state.seg === 2 &&
<ListView />
}
my code does not work and it gives me the error that
undefined is not an object (evaluating '_this2.props.navigation').
Any help will be much appreciated!
You have to send the navigation prop down to your ListView so it has access to it:
{this.state.seg === 2 &&
<ListView navigation={this.props.navigation} />
}
I'm using react native List to generate a Dynamic list using a custom data array and in the ListItem. I am using nested checkbox in every list item and I can't set the switch. I tried it by setting array of state but it doesn't seem to work.
This is my list
const DashboardList = props => (
<List
style={props.ListStyle}
dataArray={props.ListData}
renderRow={item => <ListContent ListData={item} />}
/>
);
This is my listItem
class ListContent extends Component {
static navigationOptions = {
title: "ListContent",
header: null
};
constructor(props) {
super(props);
this.state = {
IsContentVisible: false
};
}
render() {
return (<ListItem>
<View>
<View>
<Left>
<View>
<CheckBox
checked={this.state.checked}
onPress={checked => {
this.setState({ checked: !this.state.checked });
this.props.CheckBoxChange(this.props.ListItem,
checked);}}/>
</View>
<View>
<Image
source={this.props.ListItem.DataFolderContent[0].Image}
resizeMethod="auto"
resizeMode="contain"
/>
</View>
<View>
<Text>
{this.props.ListItem.Name}
</Text>
</View>
</Left>
<Body>
<View>
<Badge style={{ backgroundColor: "#eeae30" }}>
<Text>{this.props.ListItem.DataFolderContent.length}
</Text>
</Badge>
</View>
</Body>
<Right >
<Switch
onTintColor="#eeae30"
value={this.state.switched}
onValueChange={() => {
this.setState({ switched: !this.state.switched });
this.props.SwitchToggled(this.props.ListItem);
}}
/>
</Right>
</View>
</View>
</ListItem>;
}
}