reactjs - React Native setState 不会导致渲染
问题描述
我是 react native 的完整初学者,现在我遇到了更新问题。我正在使用react-native-paper
和typescript
。
在我的应用程序中,我想按下一个按钮,然后文本字段应该更改其文本。
问题出在按钮或被调用函数上,因为在控制台日志中它总是"before: true after:true"
or "before: false after:false"
,但我期望的是"before: true after: false"
orvice-versa
我还有第二个文本视图,它根本没有显示。
也许有人可以告诉我我做错了什么?
我的 index.js
import * as React from 'react';
import { AppRegistry } from 'react-native';
import { Provider as PaperProvider } from 'react-native-paper';
import App from './src/App';
export default function Main() {
return (
<PaperProvider>
<App />
</PaperProvider>
);
}
AppRegistry.registerComponent('main', () => Main);
我的 MyNavigation.tsx(目前包含我的整个应用程序)。
import * as React from 'react';
import { BottomNavigation, Text, Avatar, Button, Card, Title, Paragraph, Banner } from 'react-native-paper';
import { View, Image, WebView } from 'react-native';
export default class MyNavi extends React.Component {
constructor(props, context) {
super(props, context);
this.setUnConnected = this.setUnConnected.bind(this);
}
state = {
index: 0,
routes: [
{ key: 'viewcamera', title: 'View', icon: 'remove-red-eye' },
{ key: 'viewsettings', title: 'Settings', icon: 'settings' },
{ key: 'viewhelp', title: 'How-To', icon: 'help' },
],
visible: true,
connected: false,
};
_handleIndexChange = index => { this.setState({ index }); }
setUnConnected = function () {
console.log("before: " + this.state.connected);
this.setState({ connected: !this.state.connected });
console.log("after: " + this.state.connected);
console.log("--------------");
};
ViewRoute = () =>
<View style={{ flex: 1, marginTop: 40 }}>
{/* --------- This text field does not get updated -------------*/}
<Text>connected: {this.state.connected ? 'true' : 'false'}</Text>
{/* --------- This text field is not shown at all ------------*/}
<Text>
{this.state.connected}
</Text>
<Button icon="camera" mode="contained" onPress={this.setUnConnected}>
Press me
</Button>
<View style={{ height: 400, width: 400 }}>
<WebView
source={{ uri: 'https://stackoverflow.com/' }}
style={{ marginTop: 40 }}
// onLoad={() => this.setState({ connected: true })}
/>
</View>
</View>
SettingsRoute = () => <Text>Settings</Text>;
HelpRoute = () => <View></View>
_renderScene = BottomNavigation.SceneMap({
viewcamera: this.ViewRoute,
viewsettings: this.SettingsRoute,
viewhelp: this.HelpRoute,
});
render() {
return (
<BottomNavigation
navigationState={this.state}
onIndexChange={this._handleIndexChange}
renderScene={this._renderScene}
/>
);
}
}
解决方案
你的问题来了
setUnConnected = function () {
console.log("before: " + this.state.connected);
this.setState({ connected: !this.state.connected });
console.log("after: " + this.state.connected);
console.log("--------------");
};
setState
是async
函数,更新状态需要一些时间。它不会阻止下一条语句的执行。因此,您将始终只为两个console.log
.
要获取实际更新的值,您应该在 setState 中使用回调。
setUnConnected = function () {
console.log("before: " + this.state.connected);
this.setState({ connected: !this.state.connected }, () => console.log("after: " + this.state.connected); ); //Now you will get updated value.
console.log("--------------");
};
为了这,
{/* --------- This text field is not shown at all ------------*/}
<Text>
{this.state.connected}
</Text>
this.state.connected
要么是要么true
(false
布尔值),它永远不会显示在屏幕上。如果您仍想在屏幕上看到该值,则可以使用 this hack
。
<Text>
{this.state.connected.toString()}
</Text>
更新
从文档中,
页面是延迟渲染的,这意味着页面将在您第一次导航到它时被渲染。初始渲染后,所有页面都保持渲染状态以保持其状态。
取而代之的是,
_renderScene = BottomNavigation.SceneMap({
viewcamera: this.ViewRoute,
viewsettings: this.SettingsRoute,
viewhelp: this.HelpRoute,
});
你应该使用这个版本的renderScene
,
_renderScene = ({ route, jumpTo }) => {
switch (route.key) {
case 'viewcamera':
return <ViewRoute jumpTo={jumpTo} connected={this.state.connected} setUnConnected={this.setUnConnected}/>; //Here you can pass data from state and function to your component
case 'viewsettings':
return <SettingsRoute jumpTo={jumpTo} />;
case 'viewhelp':
return <HelpRoute jumpTo={jumpTo} />;
}
}
您的完整代码应如下所示,
import * as React from 'react';
import { BottomNavigation, Text, Avatar, Button, Card, Title, Paragraph, Banner } from 'react-native-paper';
import { View, Image, WebView } from 'react-native';
const ViewRoute = (props) =>
<View style={{ flex: 1, marginTop: 40 }}>
{/* --------- This text field does not get updated -------------*/}
<Text>connected: {props.connected ? 'true' : 'false'}</Text>
{/* --------- This text field is not shown at all ------------*/}
<Text>
{props.connected.toString()}
</Text>
<Button icon="camera" mode="contained" onPress={props.setUnConnected}>
Press me
</Button>
<View style={{ height: 400, width: 400 }}>
<WebView
source={{ uri: 'https://stackoverflow.com/' }}
style={{ marginTop: 40 }}
// onLoad={() => this.setState({ connected: true })}
/>
</View>
</View>
const SettingsRoute = () => <Text>Settings</Text>;
const HelpRoute = () => <View></View>
export default class MyNavi extends React.Component {
constructor(props, context) {
super(props, context);
this.setUnConnected = this.setUnConnected.bind(this);
}
state = {
index: 0,
routes: [
{ key: 'viewcamera', title: 'View', icon: 'remove-red-eye' },
{ key: 'viewsettings', title: 'Settings', icon: 'settings' },
{ key: 'viewhelp', title: 'How-To', icon: 'help' },
],
visible: true,
connected: false,
};
_handleIndexChange = index => { this.setState({ index }); }
setUnConnected = function() {
console.log("before: " + this.state.connected);
this.setState({ connected: !this.state.connected });
console.log("after: " + this.state.connected);
console.log("--------------");
};
_renderScene = ({ route, jumpTo }) => {
switch (route.key) {
case 'viewcamera':
return <ViewRoute jumpTo={jumpTo} connected={this.state.connected} setUnConnected={this.setUnConnected}/>; //Here you can pass data from state and function to your component
case 'viewsettings':
return <SettingsRoute jumpTo={jumpTo} />;
case 'viewhelp':
return <HelpRoute jumpTo={jumpTo} />;
}
}
render() {
return (
<BottomNavigation
navigationState={this.state}
onIndexChange={this._handleIndexChange}
renderScene={this._renderScene}
/>
);
}
}
推荐阅读
- elasticsearch - 如何在以下 Elastic 搜索中添加自动完成功能?
- angular - 如何使用 TS 以 pdf 格式下载 Angular 8 中的页面
- r - 通过R中的迭代计算向量范围内的事件
- go - Go中的数独递归回溯
- javascript - 使用 Jest Mock Function / Jest spyOn 测试带参数的导入函数
- python - 如何将小数点后的前 14 位浮点数与另一个浮点数的前 14 位进行比较?
- python - 使用朴素贝叶斯做多分类
- unix - 根据unix中文件的条件删除重复行
- flowtype - JavaScript 流类型 - 类型参数未绑定到函数的返回值
- matillion - 如何在 Matillion 中导入环境