TypeError : props.navigation.getParam is not a function. In(props.navigation.getParam('name') - react-native

I am facing issue on TypeError : props.navigation.getParam is not a function. In (props.navigation.getParam('name'). I am using reactNavigation version 5.x. this code is working in reactNavigation 3. What am I doing wrong?
Here is my code
export default class ChatScreen extends Component {
static navigationOption = ({ navigation }) => {
return {
title: navigation.getParam('name', null)
}
}
constructor(props) {
super(props);
this.state = {
person:{
name:props.navigation.getParam('name'),
phone:props.navigation.getParam('phone'),
// name:'Raushan',
// phone:9931428888
},
textMessage: ''
};
}
Error in state section value.
Stack navigator
`
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Auth">
<Stack.Screen name="AuthLoading" component={AuthLoadingScreen} />
<Stack.Screen name="App" component={HomeScreen} options={{ title: 'Chats' }}/>
<Stack.Screen name="Chat" component={ChatScreen} options={({ route }) => ({ title: route.params.name })}/>
<Stack.Screen name="Auth" component={LoginScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
`
and Navigate screen
onPress={()=>this.props.navigation.navigate('Chat',item)}

use props.route.params.name this is working
this.state = {
person:{
name: props.route.params.name,
phone: props.route.params.phone,
},
textMessage: ''
};

Mostly you are using the latest version of React-Navigation with the same old setup.
So, You gonna pass your custom param as the second argument in the navigation function that I pointed HERE:
// Index SCREEN:=>
const IndexScreen = ({ navigation: { navigate } }) => {
return (
<View style={Styles.container}>
<FlatList
data={state}
keyExtractor={(item) => `${item.id}`}
renderItem={({ item }) => (
<TouchableOpacity
style={{ ...Styles.singleBlog, ...Styles.rowing }}
onPress={() => navigate('Previewing', { id: item.id })} // HERE
>
<Text style={Styles.blogTitle}>{`${item.title}`}</Text>
</TouchableOpacity>
)}
/>
</View>
);
};
Then you will be able to extract the id wirth a new function called params
like so:
// PREVIEWING SCREEN:=>
const PreviewScreen = ({ route: { params } }) => {
const { state } = useContext(Context);
const { id } = params;
return (
<View style={Styles.container}>
<Text>preview post with id {id}</Text>
</View>
);
};

As of version 6.x you need to use route.
function Index({ navigation }) {
return (
<View>
<Button
title="Details"
onPress={() => {
navigation.navigate('Details', {
itemId: abcdef
});
}}
/>
</View>
);
}
function DetailsScreen({ route, navigation }) {
const { itemId } = route.params;
// console.log(itemId);
// abcdef
return (
// Content...
);
}
Source: https://reactnavigation.org/docs/params

Yes I found that in version2, 3, 4 of navigation using getParam.
Link is as follows: https://reactnavigation.org/docs/2.x/params/
when using version5 of navigation using props.navigation.route.param as per documentation.
https://reactnavigation.org/docs/params/ - version5.

In class component props can be access using this keyword. So try this :
export default class ChatScreen extends Component {
static navigationOption = ({ navigation }) => {
return {
title: navigation.getParam('name', null)
}
}
constructor(props) {
super(props);
this.state = {
person: {
name: this.props.navigation.getParam('name'), // access with this.
phone: this.props.navigation.getParam('phone'), //access with this.
// name:'Raushan',
// phone:9931428888
},
textMessage: ''
};
}
}

Related

react navigation in react native, with conditional stack, and authentication

import React, { Component } from 'react'
import { Container, Content, Form, Item, Input, Label, Button,Text, Icon} from 'native-base'
import AsyncStorage from '#react-native-community/async-storage';
import authStore from '../store/authStore';
export default class Login extends Component {
constructor(props){
super(props);
this.state={
email:'',
password:''
}
}
handleLogin = async () =>{
let requestObject = {
email: this.state.email,
password: this.state.password
}
authStore.userLogin(requestObject, response => {
this.storeUserData(response.data.data);
this.props.navigation.navigate('Home');
})
}
storeUserData = async (value) => {
try {
const jsonValue = JSON.stringify(value)
await AsyncStorage.setItem('#userData', jsonValue)
} catch (e) {
console.log(e);
}
}
render() {
return (
<Container>
<Content contentContainerStyle={{flex: 1, justifyContent:'center'}}>
<Form style={{margin:10}}>
<Item rounded last style={{margin:10}}>
<Icon active type="FontAwesome" name='user' />
<Input placeholder='User Name'
onChangeText={(email)=>this.setState({email})}
value={this.state.email}/>
</Item>
<Item rounded last style={{margin:10}}>
<Icon active type="FontAwesome" name='key' />
<Input placeholder='Password'
secureTextEntry
onChangeText={(password)=>this.setState({password})}
value={this.state.password}/>
</Item>
<Button rounded block style={{margin:10}} onPress={() => this.handleLogin()}>
<Text>Sign-In</Text>
</Button>
</Form>
</Content>
</Container>
)
}
}
const AuthStack = createStackNavigator();
AuthStackScreen = () =>
<AuthStack.Navigator>
<AuthStack.Screen name="Login" component={Login} />
</AuthStack.Navigator>
HomeStackScreen = () =>
<HomeStackDrawer.Navigator>
<HomeStackDrawer.Screen name="Home" component={HomeScreen}/>
<HomeStackDrawer.Screen name="Form" component={FormScreen}/>
<HomeStackDrawer.Screen name="Logout" component={Logout}/>
</HomeStackDrawer.Navigator>
export default class App extends Component{
constructor(props){
super(props);
this.state={
isloggedIn:false
}
this.loginStatusCheck();
}
loginStatusCheck = async () =>{
const userToken = await AsyncStorage.getItem('#accessToken');
if (userToken) {
this.setState({isloggedIn:true})
} else {
this.setState({isloggedIn:false})
}
}
render(){
return(
<NavigationContainer>
{this.state.isloggedIn ? <HomeStackScreen/> : <AuthStackScreen/>}
</NavigationContainer>
)
}
}
This is my App.js, I am checking if the user is logged in or not, then loading the Navigation stack accordingly. I know the problem, If I Logout, I want to navigate to the sign-in component, but this.props.navigation.navigate('Login') gives error. because I am not returning the Login route. How to solve this issue? Also, when I Log in same issue, as the Login is not present in the stack.
Thank you in advance
Included the login component
You will have to do some changes to fix this issue. Your problem is you are trying to access a screen in a navigation stack which is not there.
And the biggest problem is using a state variable in App.js to handle the switch of navigation stacks. You can resolve this by maintaining the login status in a context in your application. You can update it from other screens as well. Once you update the login status you dont have to worry about the navigation and your condition in the App.js will manage that for you.
The code should be something like below. I have given a sample Login component which will update the context. You will have to switch to functional component. From your code i dont see any problem of doing that.
const AppContext = createContext({
isloggedIn: {},
setLoggedIn: () => {},
});
const Login = () => {
const { setLoggedIn } = useContext(AppContext);
return (
<View>
<Button onPress={() => setLoggedIn(true)} />
</View>
);
};
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
isloggedIn: false,
loading: true,
};
this.loginStatusCheck();
}
setLoggedIn = value => {
this.setState({ isloggedIn: value });
};
loginStatusCheck = async () => {
const userToken = await AsyncStorage.getItem('#accessToken');
if (userToken) {
this.setState({ isloggedIn: true, loading: false });
} else {
this.setState({ isloggedIn: false, loading: false });
}
};
render() {
if (this.state.loading) return <ActivityIndicator />;
return (
<AppContext.Provider
value={{
isloggedIn: this.state.isloggedIn,
setLoggedIn: this.setLoggedIn,
}}>
<NavigationContainer>
{this.state.isloggedIn ? <HomeStackScreen /> : <AuthStackScreen />}
</NavigationContainer>
</AppContext.Provider>
);
}
}
Hope this helps.

Cant navigate to next screen

I am trying to navigates screens with a stack navigator. The Idea is, my app will navigate from my list of chats, too the chat screen. However when I try to navigate to the next screen, I receive an error saying "undefined is not an object" on this.props.navigation. Here is what my code looks like:
MainTabNavigator (Contains my stack navigator)
const ChatListStack = createStackNavigator({
ChatList:ChatListScreen,
ChatView:ChatScreen,
});
ChatListStack.navigationOptions = {
tabBarLabel: 'ChatList',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={Platform.OS === 'ios' ? `ios-options${focused ? '' : '-outline'}` :
'md-options'}
/>
),
};
ChatListScreen (Where the navigation starts from)
export default class ChatListScreen extends Component {
constructor(props) {
super(props);
}
static navigationOptions = {
title: "Chats"
};
renderRow({ item }) {
return (
<TouchableHighlight
onPress={() => this.props.navigation.navigate("ChatView")}
>
<ListItem
roundAvatar
title={item.name}
subtitle={item.subtitle}
avatar={{ uri: item.avatar_url }}
/>
</TouchableHighlight>
);
}
goToChat() {}
render() {
return (
<View style={styles.mainContainer}>
<SearchBar
lightTheme
icon={{ type: "font-awesome", name: "search" }}
placeholder="Type Here..."
/>
<List style={styles.listContainerStyle}>
<FlatList
data={users}
renderItem={this.renderRow}
keyExtractor={item => item.name}
/>
</List>
</View>
);
}
}
Chat(This is the target Chat screen)
export default class ChatScreen extends Component {
constructor() {
super();
this.state = {
messages: []
};
}
componentWillMount() {
this.setState({
messages: [
{
_id: 1,
text: "Hello test",
createdAt: new Date(),
user: {
_id: 2,
name: "dude"
}
}
]
});
}
render() {
return (
<GiftedChat
messages={this.state.messages}
onSend={message => this.onSend(message)}
user={{
_id: 1
}}
/>
);
}
}
to solve this problem you must make a function to handle navigation then bind it in the contractor then send it in your Touchableopacity

React-native : Dynamically update header title in stack navigator

I have made a custom component for header title(stack navigator)which shows user name along with some image.
On this page I have to edit the username and on success Update it in header as well
So my question is How to change/update title dynamically?
This can be done using the navigation props.
You can use this.props.navigation.state.params in a component to set a new property. Call:
navigation.setParams({ param: value })
See the documentation on headers for more detail.
For React Navigation version 1.x, 2.x, 3.x and 4.x, you can simply change the header by using the method shown in the code below, or the one in the original documentation: React Navigation - using params in the title
static navigationOptions = ({ navigation }) => {
const edit = navigation.getParam('edit', false);
if(edit){
return {
headerTitle: 'Edit Page',
};
}else{
return {
headerTitle: 'Normal Page',
};
}
};
For version 5.x and above, you may refer to the code below. Here are the links for the official documentation and example in expo.
import * as React from 'react';
import { View, Text, Button } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Profile"
onPress={() =>
navigation.navigate('Profile', { name: 'Custom profile header' })
}
/>
</View>
);
}
function ProfileScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Profile screen</Text>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'My home' }}
/>
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={({ route }) => ({ title: route.params.name })}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
In React 5.0 or above you could do the following if you want to use a Class Component:
componentDidMount() {
this.props.navigation.setOptions({
title: `Your Updated Title`,
})
}
With React Navigation 5 and React Navigation 6 you can do this like this,
set Params in your component
props.navigation.navigate("ProductDetailScreen", {
productId: itemData.item.id,
productTitle: itemData.item.title,
});
And display it
<Stack.Screen
name="ProductDetailScreen"
component={ProductDetailScreen}
options={({ route }) => ({ title: route.params.productTitle })} // what
need to add
/>
or you can do this in your component with useEffect hooks
useEffect(() => {
props.navigation.setOptions({
title: productTitle,
});
}, [productTitle, props.navigation]);
navigation.setOptions({ title: 'Updated!' })
Reference.
the code that shows in the part below is for the version of react-navigation 2.x
you can try the following:
in my case I have the configuration of navigation in a file called, app-navigator.js
const ChatStackNavigator = createStackNavigator(
{
People: ListPeopleScreen, // People Screen,
Screen2: Screen2
},
{
initialRouteName: 'People'
navigationOptions: ({navigation}) => ({
header: <AppBar title={navigation.getParam('appBar', {title: ''}).title}/>
}),
cardStyle: {
backgroundColor: 'white'
}
}
);
The screen file would be as follows:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {List, ListItem} from 'react-native-elements';
class ListPeopleScreen extends Component {
list = [
{
name: 'Amy Farha',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
subtitle: 'Vice President'
},
{
name: 'Chris Jackson',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
subtitle: 'Vice Chairman'
}
];
componentDidMount() {
this.props.navigation.setParams({
appBar: {
title: 'Clientes'
}
});
}
render() {
return <List
containerStyle={{marginBottom: 30}}
>
{
this.list.map((item) => (
<ListItem
roundAvatar
avatar={{uri: item.avatar_url}}
key={item.name}
title={item.name}
/>
))
}
</List>
};
}
export default connect(null)(ListPeopleScreen);
NOTE: in my case I am using redux, and the library of components react-native-elements
In version 3.x and 4.x this can be done using static navigationOptions function,
For class compenents,
class MyComponent extends Component {
static navigationOptions = ({navigation}) => {
return {
title: navigation.getParam('title', 'Fallback title');
};
}
updateHeader = () => {
// dynamically update header
navigation.setParams({title: 'MyComponent'});
}
render() {
// call updateHeader on click of any component
}
}
For functional components,
const MyComponent = (props) => {
const updateHeader = () => {
// dynamically update header
navigation.setParams({title: 'MyComponent'});
}
// call updateHeader on click of any component
}
MyComponent.navigationOptions = ({navigation}) => ({
title: navigation.getParam('title', 'Fallback title'),
})
for react navigation Version: 5.x
const ProductDetailScreen = props => {
const { productId } = props.route.params;
const { productTitle } = props.route.params;
props.navigation.setOptions({ title: productTitle });
return (
<View>
<Text>{productId}</Text>
</View>
);
};
for react navigation Version: 5.x
For version 4, this is work for me.
const HistoryScreen: NavigationStackScreenComponent<any, any> = (props) => {
const { navigation } = props;
useEffect(() => {
let device = props.navigation.getParam("device");
if(device) {
navigation.setParams({title: `History - ${device.name}`})
}
}, []);
... render view
HistoryScreen.navigationOptions = ({
navigationOptions,
navigation,
}) => ({
headerTitle: navigation.getParam("title") ? navigation.getParam("title") : "History"
});
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="OrdersScreen"
component={OrdersScreen}
options={{ title: 'My Orders' }}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
For React-Navigation v3, I used the following command to change the title of a stack:
Class component:
this.props.navigation.setParams({ title: res.title });
Function component:
props.navigation.setParams({ title: res.title });
If you use createStackNavigator you can do like this:
createStackNavigator({
// For each screen that you can navigate to, create a new entry like this:
Profile: {
// `ProfileScreen` is a React component that will be the main content of the screen.
screen: ProfileScreen,
// When `ProfileScreen` is loaded by the StackNavigator, it will be given a `navigation` prop.
// Optional: When deep linking or using react-navigation in a web app, this path is used:
path: 'people/:name',
// The action and route params are extracted from the path.
// Optional: Override the `navigationOptions` for the screen
navigationOptions: ({ navigation }) => ({
title: `${navigation.state.params.name}'s Profile'`,
}),
},
...MyOtherRoutes,
});
from the doc
call it like this:
navigation.navigate('Profile', {_id: item._id, name: item.screenName})}

React-native: How to get navigationOptions with Custom TabBarComponent

I'm new to react native and i'm trying to build a custom tab bar but i'm facing a problem when trying to display icons tab bar.
Here what i achieve so far.
Here my Custom TabBar component:
class TabBar extends Component {
renderItem = (route, index) => {
const {
navigation,
jumpToIndex,
} = this.props;
const isCapture = route.routeName === 'AddExpenses';
const focused = index === navigation.state.index;
const color = focused ? activeTintColor : inactiveTintColor;
if (isCapture === true) {
return (
<TouchableOpacity
key={route.key}
style={Styles.tab}
onPress={() => (navigation.navigate('AddExpensesModal'))}
>
<Ionicons
name={ioniconsByPlatform('add-circle')}
style={Styles.icon}
size={26}
/>
</TouchableOpacity>
);
}
return (
<TouchableWithoutFeedback
key={route.key}
style={Styles.tab}
onPress={() => (isCapture ? navigation.navigate('CaptureModal') : jumpToIndex(index))}
>
<View style={Styles.tab}>
<Text style={{ color }}>{route.routeName}</Text>
</View>
</TouchableWithoutFeedback>
);
}
render() {
const {
navigation,
} = this.props;
const {
routes,
} = navigation.state;
return (
<View style={Styles.tabBar}>
{routes && routes.map(this.renderItem)}
</View>
);
}
}
export default TabBar;
My Tab Navigator:
const MainTabNavigator = TabNavigator({
Summary: { screen: SummaryScreen },
AddExpenses: { screen: ExpensesScreen },
Expenses: { screen: ExpensesScreen },
}, {
tabBarComponent: TabBar,
});
export default MainTabNavigator;
And an example of a screen where i try to set my TabBarIcon:
const SummaryScreen = () => (
<View style={Styles.container}>
<Text>Summary</Text>
</View>
);
SummaryScreen.navigationOptions = {
title: 'Summary',
tabBarIcon: props => <TabBarIcon {...props} name="pulse" />,
};
export default SummaryScreen;
I want to be able to display my tab bar icons thanks to the navigationOptions property.
Do you have any idea how i can do this ?
If you feel TabNavigator is not powerful enough(which I think it's far from powerful), you could always customize a navigator view.
Here is my notes for customize a navigator view to replace TabNavigator:
export default class SectionTabView extends React.Component {
static propTypes = {
navigation: PropTypes.object
};
constructor(props) {
super(props);
}
render() {
const {router, navigation} = this.props;
const {routes, index} = navigation.state;
/**
* ActiveScreen is the current screen you see when you change you navigation state in tab bar
*/
const ActiveScreen = router.getComponentForState(navigation.state);
return (
<View style={Styles.section_container}>
<ActiveScreen
navigation={addNavigationHelpers({
...navigation,
state: routes[index],
})}
/>
<SectionTabBar navigation={navigation}/>
</View>
);
}
}
export default class SectionTabBar extends React.Component {
static propTypes = {
navigation: PropTypes.object
};
constructor(props) {
super(props);
}
getTabButtomGroupView() {
const {navigation} = this.props;
const {routes, index} = navigation.state;
let tabButtomGroupView = [];
routes.map((route) => {
let styles = [Styles.eventSection_tab];
const isClicked = routes[index].routeName === route.routeName;
if(isClicked){
styles.push(Styles.eventSection_tabClicked);
}
tabButtomGroupView.push(
<TouchableOpacity
onPress={() => {
/**
* when the routeName is equal to current routeName, we should stop navigate action
*/
if (routes[index].routeName === route.routeName) {
return;
}
navigation.navigate(route.routeName);
}}
style={styles}
key={route.routeName}>
<Text style={{color:'white'}}>{SectionRouteConfig[route.routeName].navigationOptions.title}</Text>
</TouchableOpacity>
)
});
return tabButtomGroupView;
}
render() {
return (
<View style={Styles.section_tabContainer}>
{this.getTabButtomGroupView()}
</View>
);
};
}
//SectionRouteConfig.js
export const sectionRouteConfig = {
XXX: {
screen: XXX, navigationOptions: {
title: XXX
}
},
XXX: {
screen: XXX, navigationOptions: {
title: XXX
}
}
};
export const SectionNavigator = createNavigator(TabRouter(sectionRouteConfig))(SectionTabView);
//Usage
render() {
const {dispatch, navigationState} = this.props;
return (
<SectionNavigator
navigation={
addNavigationHelpers({
dispatch: dispatch,
state: navigationState
})
}
/>
)
}
by the way I also use redux.
If those codes are too much for you , you can check the official example here:https://github.com/react-community/react-navigation/blob/master/examples/NavigationPlayground/js/CustomTabs.js

How to call Screen / Component class method from react-navigation Header

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 });