如何传递“this.state"React Navigation 5 中的组件到屏幕 [英] How to pass "this.state" of a Component to a Screen in React Navigation 5
问题描述
我是 React Native 的新手,我刚刚开始学习 ReactNavigation.
我正在开发的应用旨在在您玩棋盘游戏时跟踪玩家和积分.这是App.js
的代码:
import * as React from 'react';从反应"导入{组件};import { StyleSheet, Text, View, Button, Alert } from 'react-native';从'@react-navigation/native' 导入 { NavigationContainer };import { create StackNavigator } from '@react-navigation/stack';从'./player'导入{播放器};const Stack = createStackNavigator();导出默认类 BoardGameApp 扩展组件{构造函数(道具){超级(道具);this.state={ playerTable:[] }}使成为(){让 numOfPlayers = 4const totNumOfTerritories = 48返回 (<导航容器><Stack.Navigator initialRouteName="Home"><Stack.Screen name="Home";组件={HomeScreen}/></Stack.Navigator></NavigationContainer>);}}功能主屏幕(){返回(<视图样式={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><Button title="添加新玩家";onPress={() =>this.setState({ 玩家表: [...this.state.playerTable,{玩家姓名:随便"},]})}></按钮>/* 这是注释{this.state.playerTable.map(功能(播放器){return <玩家领土={totNumOfTerritories/numOfPlayers}/>;})} 评论到此结束 */</查看>);}
所以基本上应该发生的是,每当我按下按钮时,一个由 {playerName: "whatever"}
组成的对象应该被添加到 PlayerTable[]
数组存在于 BoardGameApp 的状态中,然后我接下来要做的是映射这个数组并为数组中存在的每个对象 {playerName: "whatever"}
渲染一个 Player 组件.当所有这些都发生在 App 组件中而不使用屏幕时,一切都很好,但当然看起来很糟糕.然而,一旦我开始使用屏幕,当我按下手机上的按钮时,它会给我错误 undefined is not an object (evaluating '_this2.setState')
因为我猜它不识别什么";这个"是.
我正在按照 Cs50 课程 2018 学习 ReactNative,其中ScreenProps"仍然可用.我做了一些研究,我认为我的答案应该在 Initial Params
、React Context
或 Redux
附近,即使我仍然不知道这些概念,但是每当我尝试查找文档或 Youtube 时,它只会给我提供比仅将状态从对象传递到屏幕更复杂的东西.所以这就是我最终决定在这里问这个问题的原因.
工作示例:
您可以使用 Context API 解决它:
import React, { Component, createContext, useContext } from 'react';import { StyleSheet, Text, View, Button, Alert } from 'react-native';从'@react-navigation/native' 导入 { NavigationContainer };从'@react-navigation/stack' 导入 { createStackNavigator };//从 './player' 导入 { Player };const Stack = createStackNavigator();const ParentContext = createContext();导出默认类 BoardGameApp 扩展组件 {构造函数(道具){超级(道具);this.state = { playerTable: [] };}addPlayer = (玩家) =>{console.log('数据添加:', [...this.state.playerTable, player]);this.setState({playerTable: [...this.state.playerTable, player],});};使成为() {让 numOfPlayers = 4;const totNumOfTerritories = 48;返回 (<ParentContext.Provider value={this.addPlayer}><导航容器><Stack.Navigator initialRouteName="Home"><Stack.Screen name="Home";组件={HomeScreen}/></Stack.Navigator></NavigationContainer></ParentContext.Provider>);}}功能主屏幕(){const addPlayer = useContext(ParentContext);返回 (<视图样式={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><按钮title="添加新玩家";onPress={() =>{addPlayer({ playerName: 'whatever' });}}></按钮></查看>);}const 样式 = StyleSheet.create({});
根据@satya 给出的评论,旧解决方案不是正确的方法,因此请避免使用它,但我将其保留以备将来参考:
import * as React from 'react';从反应"导入{组件};import { StyleSheet, Text, View, Button, Alert } from 'react-native';从'@react-navigation/native' 导入 { NavigationContainer };从'@react-navigation/stack' 导入 { createStackNavigator };//从 './player' 导入 { Player };const Stack = createStackNavigator();导出默认类 BoardGameApp 扩展组件 {构造函数(道具){超级(道具);this.state = { playerTable: [] };}addPlayer = (玩家) =>{console.log('hi:', [...this.state.playerTable, player]);this.setState({playerTable: [...this.state.playerTable, player],});};使成为() {让 numOfPlayers = 4;const totNumOfTerritories = 48;返回 (<导航容器><Stack.Navigator initialRouteName="Home"><堆栈屏幕名称=家"组件={() =><HomeScreen onClick={this.addPlayer}/>}/></Stack.Navigator></NavigationContainer>);}}功能主屏幕({ onClick }){返回 (<视图样式={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}><按钮title="添加新玩家";onPress={() =>{onClick({ playerName: 'whatever' });}}></按钮></查看>);}const 样式 = StyleSheet.create({});
I am new to React Native and I just started learning ReactNavigation.
The app that I'm working at is meant to keep track of players and points while you're playing a board game. Here's the code of 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>
);
}
So basically what should happen is that whenever I press the Button, an object consisting of {playerName: "whatever"}
should be added to the PlayerTable[]
array present in the state of BoardGameApp, and then what I subsequently do is that I map over this array and render a Player component for each object {playerName: "whatever"}
present in the array. When all of this was happening inside the App component without using screens everything was fine, but of course it looked awful.
Once I started using screens however, when I press the Button on my phone it gives me the error undefined is not an object (evaluating '_this2.setState')
because I guess it doesn't recognize what "this" is.
I am learning ReactNative by following the Cs50 course 2018 where "ScreenProps" were still available. I made some research and I think that my answer should be somewhere around Initial Params
, React Context
or Redux
even if I still don't know these concepts, however whenever I try to look up on the docs or on Youtube, it just gives me way more complicated stuff than just passing a state from an object to a screen. So this is why I ultimately decided to ask this question here.
Working Example: Expo Snack
Console Output:
You can solve it using 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({});
Old solution which was not the right way according to comment given by @satya so avoid it but I am keeping it in answer for future ref:
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({});
这篇关于如何传递“this.state"React Navigation 5 中的组件到屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!