【问题标题】:Run function in parent component from child - React Navigator screen w/o redux从子组件在父组件中运行功能 - 不带 redux 的 React Navigator 屏幕
【发布时间】:2018-03-01 07:41:21
【问题描述】:

我正在使用 react-native-i18n、react-native-popup-menu、react-navigation + expo(但我想尽快弹出)。当用户可以选择语言(自动检测或强制:英语、德语等)和一两个其他设置时,我想创建设置屏幕。

我正在尝试使用 AsyncStorage 来存储用户的偏好。 当用户更改设置应用程序时,我想在 AsyncStorage 和 App.js 的状态对象中设置数据(如果需要刷新主组件/完整应用程序)。但是我使用道具有问题。

App.js 片段:

const navOpt = ({ navigation }) => ({   
  headerStyle: { backgroundColor: 'blue', elevation: null },
  headerRight: (<Menu>
    <MenuTrigger><MyIcon name="more" /></MenuTrigger>
    <MenuOptions>
      <MenuOption onSelect={() => navigation.navigate('Settings')} text='Settings' />
    </MenuOptions>
  </Menu>),
 });

const RootNav = StackNavigator({
  Home: { screen: HomeScreen },
  Settings: { screen: SettingsScreen }
}, {
  navigationOptions: navOpt
});


export default class App extends Component {
  constructor(props) {
    super(props);      
    this.langHandler = this.langHandler.bind(this);

    this.state = {
      isLoadingComplete: false,
      currentLang: '',
      selectedLang: null,
      selectedTheme: null
    };
   }

  async componentWillMount() {    
    try {
    AsyncStorage.multiGet(['lang', 'theme'],   (err, stores) => {
        this.setState({ selectedLang: stores[0].lang });
        this.setState({ selectedTheme: stores[0].theme });    
    });
    } catch (e) {
      console.log(e);
      return;
    }

   try {
      await I18n.initAsync();
    } catch (e) {
      console.log(e);
      return;
    }
    console.log(this.state.selectedLang);
    if (this.state.selectedLang != null && this.state.selectedLang !== '') {
        this.setState({ currentLang: this.state.selectedLang });
        } else {
        this.setState({ currentLang: I18n.locale });
        }
    this.setState({ isLoadingComplete: true });   
    console.log(this.state);
  }

  langHandler(lang) {
    console.log(`xx${lang}`);
    this.setState({
        isLoadingComplete: false
    });
}

  render() {
  if (this.state.isLoadingComplete) return (<MenuProvider><RootNav /></MenuProvider>);
    return <View />;
  }
}

SettingsScreen.js - 这是最简单的版本:

import React, { Component } from 'react';
import { StyleSheet, View, Button, TextInput, AsyncStorage } from 'react-native';

class SettingsScreen extends Component {
  static navigationOptions = {
    title: 'Settings',
  };
  constructor(props) {
    super(props);
    this.state = {
      text: ''
    };
  }
    saveData() {
      AsyncStorage.setItem('lang', this.state.text);
      this.props.langHandler(this.state.text);
    }
    render() {
      return (
        <View style={styles.container}>
          <View>
              <TextInput onChangeText={(text) => this.setState({ text })} />
             <Button title='set' onPress={() => this.saveData()} />
          </View>
        </View>
      );
    }
  }

我正在尝试设置类似

 const RootNav = StackNavigator({
      Home: { screen: HomeScreen },
      Settings: { screen: props => <SettingsScreen (...props) />}

但不工作。 也许我需要使用 Redux?但是如果有可能避免这种情况会更好:) 也许我应该以不同的方式做所有事情?

感谢您的宝贵时间。 最好的问候

【问题讨论】:

    标签: react-native react-navigation


    【解决方案1】:

    您正在寻找的是screenProps。您必须将langHandler 添加到RootNav screenProps。

    render() {
      const screenProps = {
         langHandler: this.langHandler,
      };
    
      if (this.state.isLoadingComplete) {
        return (
           <MenuProvider>
              <RootNav screenProps={screenProps} />
          </MenuProvider>);
    
      }
      return <View />;
    }
    

    然后您就可以在您的SettingsScreen 中使用this.props.screenProps.langHandler 访问langHandler

    saveData() {
      AsyncStorage.setItem('lang', this.state.text);
      this.props.screenProps.langHandler(this.state.text);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-09
      • 2021-03-23
      • 2022-01-07
      • 1970-01-01
      • 2020-11-17
      • 2021-04-02
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      相关资源
      最近更新 更多