Javascript React Native:TextInput与状态和异步存储
当我在键盘上打字时,我看到一些关于输入在JS代码之前的警告 Native TextInput(react Native非常棒)比JS早4个事件-尝试让JS更快 因此,添加了Javascript React Native:TextInput与状态和异步存储,javascript,android,ios,reactjs,react-native,Javascript,Android,Ios,Reactjs,React Native,当我在键盘上打字时,我看到一些关于输入在JS代码之前的警告 Native TextInput(react Native非常棒)比JS早4个事件-尝试让JS更快 因此,添加了debounce,并使其“起作用”: 顺便说一句:我现在正在做一些“道具钻孔”,但计划使用 警告似乎已通过添加去盎司(1)。。但我看到了一些奇怪的问题——特别是在iPhone8plus模拟器上(在iPhone6模拟器或Android设备上没有看到相同的问题) 观察到的问题: TextInput不展开-只需添加scolling
debounce
,并使其“起作用”:
顺便说一句:我现在正在做一些“道具钻孔”,但计划使用
警告似乎已通过添加去盎司(1)。。但我看到了一些奇怪的问题——特别是在iPhone8plus
模拟器上(在iPhone6模拟器或Android设备上没有看到相同的问题)
观察到的问题:
TextInput
不展开-只需添加scolling(在iPhone 6和Android设备上展开)
平面列表中的一些布局问题
——似乎在查找列表元素的正确高度时遇到了问题
快速JS代码和保存到状态
和异步存储
的最佳实践是什么?
(1) 除了使用debounce
之外,还有一种方法是使用并添加某种计时器,在一段时间后将状态推送到父组件。。但我不确定这是否会使JS代码更快。所以我没试过
更新(再次)
我开放了整个代码的源代码,因为当代码嵌套在一起时,很难在一篇文章中给出所有需要的信息
整个代码如下所示:
(我知道我的代码可能看起来很混乱,但我仍在学习….)
我不希望人们使用PR来修复我的代码(尽管这会非常棒),但只要给我一些代码指导,告诉我如何正确处理state
和AsyncStorage
的TextInput
我知道我有一些风格上的问题-我很想解决它们,但也要遵守SO并保持主题
更新二
我删除了forceUpdate
并将FadeImage
替换为仅使用Image
但我仍然看到一些奇怪的问题
这是我的密码
import React from 'react'
import {
StyleSheet,
SafeAreaView,
FlatList,
StatusBar,
ImageBackground,
AsyncStorage,
Platform,
} from 'react-native'
import SplashScreen from 'react-native-splash-screen'
import LinearGradient from 'react-native-linear-gradient'
import { debounce } from 'lodash'
import Section from './Section'
import ButtonContact from './ButtonContact'
import { data } from '../data.json'
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
data,
indexRef: data.reduce((result, item, index) => {
result[item.title] = index
return result
}, {}),
ready: false,
}
}
async componentDidMount() {
SplashScreen.hide()
try {
let BusinessPlan = await AsyncStorage.getItem('BusinessPlan')
if (BusinessPlan !== null) {
// We have data!!
let data = JSON.parse(BusinessPlan)
data = this.state.data.map(item => {
const index = data.findIndex(obj => obj.id == item.id)
const pitch = index >= 0 ? data[index].pitch : ''
return { ...item, pitch }
})
this.setState({ data, ready: true })
} else {
this.setState({ ready: true })
}
} catch (error) {
// Error retrieving data
}
}
updatePitch = (id, text) => {
// Copy the data
let data = [...this.state.data]
const index = data.findIndex(obj => obj.id == id)
data[index].pitch = text
// Update the state
this.setState({ data }, this.saveLocally(data))
}
saveLocally = data => {
try {
AsyncStorage.setItem('BusinessPlan', JSON.stringify(data))
} catch (error) {
// Well..
}
}
render() {
return (
<LinearGradient
style={{ flex: 1 }}
start={{ x: 0.0, y: 0.25 }}
end={{ x: 0.5, y: 1.0 }}
colors={['#000000', '#808080', '#000000']}
>
<StatusBar
barStyle={'light-content'}
backgroundColor={Platform.OS == 'iOS' ? 'transparent' : 'black'}
/>
<SafeAreaView>
<ImageBackground
source={require('../images/BackgroundImage.png')}
style={{ width: '100%', height: '100%' }}
resizeMode={'cover'}
>
<FlatList
data={this.state.data}
initialNumToRender="16"
keyExtractor={item => item.id}
renderItem={({ item }) => (
<Section
id={item.id}
title={item.title}
pitch={item.pitch}
updatePitch={debounce(this.updatePitch, 1000)}
questions={item.questions}
ready={this.state.ready}
/>
)}
ListFooterComponent={<ButtonContact />}
style={{
backgroundColor: 'transparent',
borderColor: '#000',
borderWidth: StyleSheet.hairlineWidth,
}}
/>
</ImageBackground>
</SafeAreaView>
</LinearGradient>
)
}
}
const styles = StyleSheet.create({
sectionHeader: {
fontSize: 24,
marginHorizontal: 5,
},
})
从“React”导入React
进口{
样式表,
安全区域视图,
平面列表,
状态栏,
图像背景,
异步存储,
平台,
}从“反应本机”
从“反应本机启动屏幕”导入启动屏幕
从“反应本机线性渐变”导入LinearGradient
从“lodash”导入{debounce}
从“./节”导入节
从“./ButtonContact”导入ButtonContact
从“../data.json”导入{data}
导出默认类App扩展React.Component{
建造师(道具){
超级(道具)
此.state={
数据,
indexRef:data.reduce((结果、项目、索引)=>{
结果[项目名称]=索引
返回结果
}, {}),
就绪:错误,
}
}
异步组件didmount(){
SplashScreen.hide()
试一试{
让BusinessPlan=await AsyncStorage.getItem('BusinessPlan')
if(商业计划!==null){
//我们有数据!!
让data=JSON.parse(商业计划)
data=this.state.data.map(项=>{
const index=data.findIndex(obj=>obj.id==item.id)
常数节距=索引>=0?数据[索引]。节距:“”
返回{…项目,音高}
})
this.setState({data,ready:true})
}否则{
this.setState({ready:true})
}
}捕获(错误){
//检索数据时出错
}
}
UpdateTech=(id,文本)=>{
//复制数据
让数据=[…this.state.data]
const index=data.findIndex(obj=>obj.id==id)
数据[索引]。间距=文本
//更新状态
this.setState({data},this.savelocal(数据))
}
savelocal=data=>{
试一试{
AsyncStorage.setItem('BusinessPlan',JSON.stringify(数据))
}捕获(错误){
//嗯。。
}
}
render(){
返回(
项目id}
renderItem={({item})=>(
)}
ListFooterComponent={}
风格={{
背景色:“透明”,
边框颜色:“#000”,
borderWidth:StyleSheet.hairlineWidth,
}}
/>
)
}
}
const styles=StyleSheet.create({
章节标题:{
尺寸:24,
marginHorizontal:5,
},
})
(我还更新了我的git回购协议)
更新三
我对状态
和异步存储
的设置似乎可以在去盎司
的情况下正常工作。我看到的问题是因为我正在耗尽CPU(下一步要修复)。我尝试了您的代码:
- “我发现了一些奇怪的问题——特别是在iPhone8 plus上
模拟器(在iPhone 6模拟器或Android上看不到相同的情况
设备“”==>我确认了这一点
- 该应用程序大约需要100%的CPU
经过一段时间的尝试,我发现:
- “我发现了一些奇怪的问题——特别是在iPhone8 plus上
模拟器(在iPhone 6模拟器或Android上看不到相同的情况
设备“==>不正确,请稍等
TextInput
将展开
- 状态和异步存储没有问题。我没有得到任何警告
根本问题是FadeImage
中的动画:
- 该应用程序呈现许多
旋转木马
,每个旋转木马
都有AngleInvestor
,以及FadeImage
。问题是FadeImage
FadeImage
runAnimated
时长1000=>CPU过载
==>这就是为什么TextInput
add scroll需要很长时间才能展开,而FlatList
看起来有问题,但没有问题。它们只是在慢慢更新
解决方案:
- 试着评论一下FadeImage,你会发现问题消失了
- 不要像同一个tim那样启动那么多动画
import React from 'react'
import {
StyleSheet,
SafeAreaView,
FlatList,
StatusBar,
ImageBackground,
AsyncStorage,
Platform,
} from 'react-native'
import SplashScreen from 'react-native-splash-screen'
import LinearGradient from 'react-native-linear-gradient'
import { debounce } from 'lodash'
import Section from './Section'
import ButtonContact from './ButtonContact'
import { data } from '../data.json'
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
data,
indexRef: data.reduce((result, item, index) => {
result[item.title] = index
return result
}, {}),
ready: false,
}
}
async componentDidMount() {
SplashScreen.hide()
try {
let BusinessPlan = await AsyncStorage.getItem('BusinessPlan')
if (BusinessPlan !== null) {
// We have data!!
let data = JSON.parse(BusinessPlan)
data = this.state.data.map(item => {
const index = data.findIndex(obj => obj.id == item.id)
const pitch = index >= 0 ? data[index].pitch : ''
return { ...item, pitch }
})
this.setState({ data, ready: true })
} else {
this.setState({ ready: true })
}
} catch (error) {
// Error retrieving data
}
}
updatePitch = (id, text) => {
// Copy the data
let data = [...this.state.data]
const index = data.findIndex(obj => obj.id == id)
data[index].pitch = text
// Update the state
this.setState({ data }, this.saveLocally(data))
}
saveLocally = data => {
try {
AsyncStorage.setItem('BusinessPlan', JSON.stringify(data))
} catch (error) {
// Well..
}
}
render() {
return (
<LinearGradient
style={{ flex: 1 }}
start={{ x: 0.0, y: 0.25 }}
end={{ x: 0.5, y: 1.0 }}
colors={['#000000', '#808080', '#000000']}
>
<StatusBar
barStyle={'light-content'}
backgroundColor={Platform.OS == 'iOS' ? 'transparent' : 'black'}
/>
<SafeAreaView>
<ImageBackground
source={require('../images/BackgroundImage.png')}
style={{ width: '100%', height: '100%' }}
resizeMode={'cover'}
>
<FlatList
data={this.state.data}
initialNumToRender="16"
keyExtractor={item => item.id}
renderItem={({ item }) => (
<Section
id={item.id}
title={item.title}
pitch={item.pitch}
updatePitch={debounce(this.updatePitch, 1000)}
questions={item.questions}
ready={this.state.ready}
/>
)}
ListFooterComponent={<ButtonContact />}
style={{
backgroundColor: 'transparent',
borderColor: '#000',
borderWidth: StyleSheet.hairlineWidth,
}}
/>
</ImageBackground>
</SafeAreaView>
</LinearGradient>
)
}
}
const styles = StyleSheet.create({
sectionHeader: {
fontSize: 24,
marginHorizontal: 5,
},
})
render() {
console.log('render app.js')
...
<Section
id={item.id}
title={item.title}
pitch={item.pitch}
updatePitch={debounce(this.updatePitch, 1000)} // the key is here
questions={item.questions}
ready={this.state.ready}
/>