如何在 React Navigation 5 中将组件的 "this.state" 传递给屏幕
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 {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 组件内部而不使用屏幕时,一切都很好,但当然它看起来很糟糕。
然而,一旦我开始使用屏幕,当我按下 phone 上的按钮时,它会给我错误 undefined is not an object (evaluating '_this2.setState')
,因为我猜它无法识别“this”是什么。
我正在通过 2018 年的 Cs50 课程学习 ReactNative,其中“ScreenProps”仍然可用。我做了一些研究,我认为我的答案应该在 Initial Params
、React Context
或 Redux
附近,即使我仍然不知道这些概念,但是每当我尝试查找在文档或 Youtube 上,它只是给了我比将状态从对象传递到屏幕更复杂的东西。所以这就是为什么我最终决定在这里问这个问题。
工作示例:Expo Snack
控制台输出:
你可以使用上下文来解决它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({});
我是 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 组件内部而不使用屏幕时,一切都很好,但当然它看起来很糟糕。
然而,一旦我开始使用屏幕,当我按下 phone 上的按钮时,它会给我错误 undefined is not an object (evaluating '_this2.setState')
,因为我猜它无法识别“this”是什么。
我正在通过 2018 年的 Cs50 课程学习 ReactNative,其中“ScreenProps”仍然可用。我做了一些研究,我认为我的答案应该在 Initial Params
、React Context
或 Redux
附近,即使我仍然不知道这些概念,但是每当我尝试查找在文档或 Youtube 上,它只是给了我比将状态从对象传递到屏幕更复杂的东西。所以这就是为什么我最终决定在这里问这个问题。
工作示例:Expo Snack
控制台输出:
你可以使用上下文来解决它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({});