【问题标题】:How to call a function in a React Native class from a different module如何从不同的模块调用 React Native 类中的函数
【发布时间】:2019-03-11 23:21:51
【问题描述】:

在我的应用程序中,我在模块 xyz.js 中定义了一个默认类 A,它在我的导航堆栈上呈现一个页面。根据 A 类的状态变量之一,呈现的视图会有所不同。例如,如果应用程序处于“编辑模式”,则除了在应用程序不处于“编辑模式”时呈现的其他标准视图之外,还会呈现一个编辑视图。我不知道如何从不同的模块 abc.js 更改该状态变量并导致与实例化类 A 关联的视图重新呈现。在我的模块 abc.js 中,我创建了导航堆栈,并且我有一个用于 touchableHighlight 按钮的 onPress 处理程序,以将应用程序置于“编辑模式”。在该处理程序中,我尝试在 A 类中调用函数“Edit()”。但该函数似乎没有被调用。它可能与绑定有关,但我并不完全理解这个概念。

这是我所拥有的:

模块 abc.js:

import XYZ from './xyz';
import {Edit} from './xyz';
import { pencilEditButton } from './Images';

const App = createStackNavigator(
{
    Home: {
        screen: My App,

        navigationOptions: ({ navigation }) => ({
            title: 'myApp',

            headerRight: (
            <View>
                <TouchableHighlight
                    onPress={() => Edit()}
                    underlayColor="gray">
                    <View>
                        <Image source={pencilEditButton} style={styles.navigationButtonImage} />
                    </View>
                </TouchableHighlight>
            </View>
            ),
        }),
    },
}
);

export default createAppContainer(App);

模块 xyz.js:

export default class XYZ extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
        editMode: false,    
    };
  };


  // Create a method to handle the press of the edit button on the navigation bar
  Edit() {
    console.log("editMode: ", editMode);
    this.setstate({ editMode: true });
    console.log("editMode: ", editMode);
    alert('User wants to edit a mix!');
  };

render() {
  return (
        <View style={styles.container}>
           { this.state.editMode === true ?
             <TouchableHighlight 
                    onPress={this._onXPressed} 
                    underlayColor="white">
                <View style={[styles.flowRight, styles.controlButton]}>
                    <Text style={styles.buttonText}>{'Edit Mode'}</Text>
                </View>
            </TouchableHighlight>
             :

             <TouchableHighlight 
                    onPress={this._onYPressed} 
                    underlayColor="white">
                <View style={[styles.flowRight, styles.controlButton]}>
                    <Text style={styles.buttonText}>{'Non Edit Mode'}</Text>
                </View>
            </TouchableHighlight>
           }
        </View>
     );
   }
 }

如您所见,在模块 xyz.js 的类 XYZ 中的构造函数之后有一个名为“Edit()”的函数。当按下编辑按钮时,从模块 abc.js 调用此函数。但是当按下编辑按钮时,状态不会更新,警报视图不会显示,视图也不会重新渲染。如何正确调用 Edit() 以更新状态变量“editMode”并重新渲染视图?

【问题讨论】:

  • 你在哪个模块或文件中实际使用了xyz作为组件?

标签: javascript react-native bind


【解决方案1】:

如果你想遵循你正在使用的模式,它需要在你的“我的应用程序”组件中的句柄,它会在堆栈导航器中呈现。你必须使用refs 通过以下代码示例了解如何调用 Edit 函数。

import XYZ from './xyz';

export default class MyApp extends React.Component {
  static navigationOptions = ({ navigation }) => ({
    title: 'myApp',
    headerRight: navigation.state.params && navigation.state.params.edit ? (
      <View>
        <TouchableHighlight
          onPress={() => navigation.state.params.edit()}
          underlayColor="gray"
        >
          <View>
            <Image source={pencilEditButton} style={styles.navigationButtonImage} />
          </View>
        </TouchableHighlight>
      </View>
    ) : null,
  })

  constructor(props) {
    super(props);
    this.onEdit = this.onEdit.bind(this);
  }

  componentDidMount() {
    this.props.navigation.setParams({ edit: this.onEdit });
  }

  onEdit() {
    if (this.xyz_Ref) {
      this.xyz_Ref.Edit();
    }
  }

  render() {
    return (
      <View>
        <XYZ ref={ref => this.xyz_Ref = ref} />
      </View>
    );
  }
}

【讨论】:

  • 我一直在尝试您建议的答案。您的评论让我质疑我的设计模式是否合适。所以我试图将你的静态 navigationOptions ({...}) 子句移到我的模块 xyz.js 中。我认为这消除了对 refs 的需求,并且看起来应该是直截了当的。对代码的唯一更改是 onPress 行。我将其更改为 onPress={() => this._Edit}。但我收到一个错误“未定义不是对象(评估'_this3.Edit')”。我意识到我跑题了,但不知道为什么会出现这个错误。
  • 您正在标题组件内的组件内调用 Edit 方法。但是标头组件无法访问组件上下文。因此我们必须使用 navigation.state 传递对 Edit 方法的引用这就是为什么 componentDidMount 使用 this.props.navigation.setParams({ edit: this.onEdit });行来设置 Edit 方法引用并使用 navigation.state.params 访问该内部标题
  • 你的设计模式有点乱。您可以做的是不使用 refs 尝试将标志作为 isEditOn 传递给 XYZ 组件,并相应地更改组件内的 UI 和逻辑。
猜你喜欢
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 1970-01-01
相关资源
最近更新 更多