【问题标题】:How to pass "this.state" of a Component to a Screen in React Navigation 5如何将组件的“this.state”传递到 React Navigation 5 中的屏幕
【发布时间】:2021-04-08 08:22:42
【问题描述】:

我是 React Native 的新手,刚开始学习 ReactNavigation。

我正在使用的应用程序旨在在您玩棋盘游戏时跟踪玩家和分数。这是App.js的代码:

import * as React from 'react'; 
import {Component} from 'react';
import { StyleSheet, Text, View, Button, Alert } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { create StackNavigator } from '@react-navigation/stack';
import { Player } from './player';


const Stack = createStackNavigator();


export default class BoardGameApp extends Component{
  constructor(props){
      super(props);
      this.state={ playerTable:[] }
  }


  render(){

    let numOfPlayers = 4
    const totNumOfTerritories = 48

    return (

      <NavigationContainer>
        <Stack.Navigator initialRouteName="Home">
            <Stack.Screen name="Home" component={HomeScreen} />
            
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}



function HomeScreen(){
  
  return(
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button title="Add a new Player" onPress={
          () => this.setState({ playerTable: [
              ...this.state.playerTable,
              { playerName: "whatever"},
           ]
          })}>
      </Button>

      /* this is commented
      {this.state.playerTable.map(
        function(player) {
          return <Player territories={totNumOfTerritories / numOfPlayers} />;
        }
      )}  here the comment ends */

    </View>
  );
}
 

所以基本上应该发生的是,每当我按下按钮时,一个由 {playerName: "whatever"} 组成的对象应该添加到 BoardGameApp 状态中存在的 PlayerTable[] 数组中,然后我随后做的是映射这个数组并为数组中存在的每个对象{playerName: "whatever"} 渲染一个 Player 组件。当所有这些都发生在 App 组件内部而不使用屏幕时,一切都很好,但当然看起来很糟糕。 然而,一旦我开始使用屏幕,当我按下手机上的按钮时,它会给我一个错误undefined is not an object (evaluating '_this2.setState'),因为我猜它无法识别“this”是什么。

我通过 2018 年 Cs50 课程学习 ReactNative,其中“ScreenProps”仍然可用。我做了一些研究,我认为我的答案应该在Initial ParamsReact ContextRedux左右,即使我仍然不知道这些概念,但是每当我尝试查找文档或Youtube时,它只是给我提供了比将状态从对象传递到屏幕更复杂的方法。所以这就是我最终决定在这里问这个问题的原因。

【问题讨论】:

    标签: react-native react-navigation-v5


    【解决方案1】:

    工作示例:Expo Snack

    控制台输出:

    您可以使用 Context API 解决它:

    import React, { Component, createContext, useContext } from 'react';
    import { StyleSheet, Text, View, Button, Alert } from 'react-native';
    import { NavigationContainer } from '@react-navigation/native';
    import { createStackNavigator } from '@react-navigation/stack';
    // import { Player } from './player';
    
    const Stack = createStackNavigator();
    
    const ParentContext = createContext();
    
    export default class BoardGameApp extends Component {
      constructor(props) {
        super(props);
        this.state = { playerTable: [] };
      }
    
      addPlayer = (player) => {
        console.log('data added :', [...this.state.playerTable, player]);
        this.setState({
          playerTable: [...this.state.playerTable, player],
        });
      };
    
      render() {
        let numOfPlayers = 4;
        const totNumOfTerritories = 48;
    
        return (
          <ParentContext.Provider value={this.addPlayer}>
            <NavigationContainer>
              <Stack.Navigator initialRouteName="Home">
                <Stack.Screen name="Home" component={HomeScreen} />
              </Stack.Navigator>
            </NavigationContainer>
          </ParentContext.Provider>
        );
      }
    }
    
    function HomeScreen() {
      const addPlayer = useContext(ParentContext);
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Button
            title="Add a new Player"
            onPress={() => {
              addPlayer({ playerName: 'whatever' });
            }}></Button>
        </View>
      );
    }
    
    const styles = StyleSheet.create({});
    

    根据@satya 给出的评论,旧的解决方案不是正确的方法,因此请避免使用它,但我会保留它以供将来参考:

    import * as React from 'react';
    import { Component } from 'react';
    import { StyleSheet, Text, View, Button, Alert } from 'react-native';
    import { NavigationContainer } from '@react-navigation/native';
    import { createStackNavigator } from '@react-navigation/stack';
    // import { Player } from './player';
    
    const Stack = createStackNavigator();
    
    export default class BoardGameApp extends Component {
      constructor(props) {
        super(props);
        this.state = { playerTable: [] };
      }
    
      addPlayer = (player) => {
        console.log('hi:', [...this.state.playerTable, player]);
        this.setState({
          playerTable: [...this.state.playerTable, player],
        });
      };
    
      render() {
        let numOfPlayers = 4;
        const totNumOfTerritories = 48;
    
        return (
          <NavigationContainer>
            <Stack.Navigator initialRouteName="Home">
              <Stack.Screen
                name="Home"
                component={() => <HomeScreen onClick={this.addPlayer} />}
              />
            </Stack.Navigator>
          </NavigationContainer>
        );
      }
    }
    
    function HomeScreen({ onClick }) {
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Button
            title="Add a new Player"
            onPress={() => {
              onClick({ playerName: 'whatever' });
            }}></Button>
        </View>
      );
    }
    
    const styles = StyleSheet.create({});
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    相关资源
    最近更新 更多