在键盘上输入时,我看到一些关于输入在JS代码之前的警告..
Native TextInput(本机反应很棒)是JS之前的4个事件 - 尝试让你的JS更快。
所以添加了debounce
并将其设为“工作”:
...
import { debounce } from 'lodash'
...
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,
}
this.updatePitch = this.updatePitch.bind(this)
this.saveLocally = debounce(this.saveLocally, 300).bind(this)
}
...
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('data', JSON.stringify(data))
this.forceUpdate()
} catch (error) {
// Well..
}
}
render() {
...
顺便说一句:我现在正在做一些“道具钻探” - 但计划使用Context API (react 16.3)
通过添加debounce
(1),警告似乎已经消失了......但是我看到了一些奇怪的问题 - 特别是在iPhone 8 plus
模拟器上(在iPhone 6模拟器或Android上看不到相同的问题)装置)
观察到的问题:
TextInput
不展开 - 它只是添加了scolling(在iPhone 6和Android设备上展开)FlatList
中的一些布局问题 - 似乎在找到列表元素的正确高度时遇到了问题。state
和AsyncStorage
的最佳做法是什么?(1)除了使用debounce
之外的另一种方法可能是使用getDerivedStateFromProps并添加某种计时器,在一段时间后将状态推送到父组件。但是不确定这将使JS代码更快。所以没试过。
我开源了整个代码,因为当代码嵌套时很难在SO帖子中提供所有需要的信息。
整个代码在这里: https://github.com/Norfeldt/LionFood_FrontEnd
(我知道我的代码可能看起来很乱,但我还在学习......)
我不希望人们进入并使用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,
},
})
(我还更新了我的git repo)
似乎我对state
和AsyncStorage
的设置适用于debounce
。我看到的问题是因为我正在耗尽CPU(下一步要修复)。
答案 0 :(得分:3)
我尝试了你的代码:
&#34;我看到了一些奇怪的问题 - 特别是在iPhone 8 plus上 模拟器(在iPhone 6模拟器或Android上看不到相同 装置)&#34; ==&GT;我确认了这个
该应用程序需要大约100%的CPU。
经过一段时间的尝试,我发现了:
&#34;我看到了一些奇怪的问题 - 特别是在iPhone 8 plus上
模拟器(在iPhone 6模拟器或Android上看不到相同
装置)&#34; ==&GT;不对,只需等待一点TextInput
就会扩大。
state和AsyncStorage没有任何问题。我没有得到任何警告。
根问题是FadeImage
中的动画:
该应用会呈现多个Carousel
,每个Carousel
都有AngleInvestor
和FadeImage
。问题是FadeImage
FadeImage
运行Animated
,持续时间为1000 =&gt; CPU过载
==&GT;为什么TextInput
添加滚动然后需要很长时间才能展开,FlatList
看起来有问题,但不是。它们只是慢慢更新。
解决方案:
尝试发表评论FadeImage
,您会看到问题消失。
不要同时开始这么多动画。如果出现就开始(例如:Carousel
中的第一张卡片)
<强>更新强>
我遇到了您的问题:快速输入会导致setState
多次调用。
您可以使用debounce
来解决这种情况:
在App.js中
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}
/>
您可以更改延迟并观看控制台日志以查看更多信息。我试过,延迟大约500可以停止警告。
P / s:您应该尝试删除forceUpdate