gpt4 book ai didi

javascript - react native : TextInput with state and AsyncStorage

转载 作者:技术小花猫 更新时间:2023-10-29 11:06:15 25 4
gpt4 key购买 nike

在键盘上打字时,我看到一些关于输入在 JS 代码之前的警告。

Native TextInput(react native is awesome) is 4 events ahead of JS - try to make your JS faster.

因此添加了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() {
...

顺便说一句:我现在正在做一些“ Prop 钻探”——但计划使用 Context API (react 16.3)

警告似乎已经通过添加 debounce (1).. 但我看到了一些奇怪的问题 - 特别是在 iPhone 8 plus 模拟器上(没有看到在 iPhone 6 模拟器或 Android 设备上相同)

观察到的问题:

  • TextInput 不扩展 - 它只是添加滚动(在 iPhone 6 和 Android 设备上扩展)
  • FlatList 中的一些布局问题 - 似乎无法找到列表元素的正确高度..

快速 JS 代码和保存到 stateAsyncStorage 的最佳实践是什么?

(1) 除了使用 debounce 之外,还有一种方法是使用 getDerivedStateFromProps并在一段时间后添加某种计时器将状态推送到父组件。但不确定这是否会使 JS 代码更快。所以没有尝试。

更新(再次)

Open Source

我开源了整个代码,因为当代码如此嵌套时,很难在 SO 帖子中提供所有需要的信息。

完整代码在这里: https://github.com/Norfeldt/LionFood_FrontEnd

(我知道我的代码可能看起来很乱,但我仍在学习..)

我不希望人们进入并通过 PR 修复我的代码(即使它会很棒)但只是给我一些关于如何正确处理 stateAsyncStorage 用于 TextInput

我知道我有一些风格问题 - 很想解决它们,但也遵守 SO 并保持主题。

更新二

我删除了 forceUpdate 并将 FadeImage 替换为 vanilla react native Image

但我仍然看到一些奇怪的问题

Weird behavior

这是我的代码

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 仓库)

更新三

似乎我对 stateAsyncStorage 的设置在 debounce 下运行良好。我看到的问题是因为我正在耗尽 CPU(下一步要修复)。

最佳答案

我试过你的代码:

  • “我发现了一些奇怪的问题 - 特别是在 iPhone 8 plus 上模拟器(在 iPhone 6 模拟器或 Android 上看不到相同的内容设备)”==>我确认了这一点

  • 该应用占用大约 100% 的 CPU。

经过一段时间的尝试,我发现:

  • “我发现了一些奇怪的问题 - 特别是在 iPhone 8 plus 上模拟器(在 iPhone 6 模拟器或 Android 上看不到相同的内容device)"==> 不对,稍等一下 TextInput 会展开。

  • state 和 AsyncStorage 没有任何问题。我没有收到任何警告。

根本问题是 FadeImage 中的动画:

  • 应用程序呈现多个Carousel,每个Carousel 都有AngleInvestorFadeImage。问题是 FadeImage

  • FadeImage 运行持续时间为 1000 的 Animated => CPU 重载

    ==> 这就是为什么 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

关于javascript - react native : TextInput with state and AsyncStorage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50234039/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com