Javascript React Native:TextInput与状态和异步存储

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

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

Native TextInput(react Native非常棒)比JS早4个事件-尝试让JS更快

因此,添加了
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
    run
    Animated
    时长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}
                    />