如何从react-navigation标题调用Screen / Component类方法

时间:2017-02-21 20:27:55

标签: react-native react-navigation

我需要从React Navigation Header调用SearchScreen类方法。

导航器看起来像这样:

  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}
          />
        ),
      },
    }
  }

5 个答案:

答案 0 :(得分:5)

我做了以下工作:

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

答案 1 :(得分:0)

我遇到了同样的问题,可以通过以下链接解决问题。

class MyScreen extends React.Component {
    static navigationOptions = {
        header: {
            right: <Button title={"Save"} onPress={() => this.saveDetails()} />
        }
    };

    saveDetails() {
        alert('Save Details');
    }

    render() {
        return (
            <View />
        );
    }
}

来源:react-native issues 145

以下是我的代码

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

答案 2 :(得分:0)

使用FunctionComponentuseStateuseEffect的解决方案

通过以下方法引用官方文档(https://reactnavigation.org/docs/en/header-buttons.html#header-interaction-with-its-screen-component):

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 */
}

但是在使用hooks api时我无法使它正常工作。我的状态变量始终为undefined,但是在考虑了钩子api的实现方式之后,一切都变得很有意义,因此解决方案是每次更改重要的状态变量时都更新导航参数:

const [count, setCount] = useState(0);

useEffect(() => {
    props.navigation.setParams({ increaseCount });
}, [count]);

const increaseCount = () => setCount(count + 1);

答案 3 :(得分:0)

我已经解决了该问题我已经通过以下方式解决了这个问题:

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

答案 4 :(得分:0)

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