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

后端 未结 5 2062
死守一世寂寞
死守一世寂寞 2021-02-09 00:27

I need to call SearchScreen class method from a React Navigation Header.

The Navigator look like this:

  Search: {
    screen: SearchScreen,
    path: \'         


        
相关标签:
5条回答
  • 2021-02-09 00:49
    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 });
    
    0 讨论(0)
  • 2021-02-09 00:51

    I've resolved the issueI've resolved the issue be 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");
    }
    
    0 讨论(0)
  • 2021-02-09 01:02

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

    0 讨论(0)
  • 2021-02-09 01:03

    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);
    
    0 讨论(0)
  • 2021-02-09 01:11

    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);
    
    0 讨论(0)
提交回复
热议问题