在键盘上打字时,我看到一些关于输入在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() {
  ...
顺便说一句:我现在正在做一些“ Prop 钻探”-但计划使用Context API (react 16.3)
通过添加debounce(1),警告似乎已经消失了。但是我看到了一些奇怪的问题-特别是在iPhone 8 plus模拟器上(在iPhone 6模拟器或Android设备上看不到同样的问题)
观察到的问题:
  • TextInput不会扩展-它只会添加scoling(在iPhone 6和Android设备上扩展)
  • FlatList中的某些布局问题-似乎在查找列表元素的正确高度时遇到问题。。

  • 快速JS代码并将其保存到stateAsyncStorage的最佳实践是什么?
    (1)除了使用debounce之外,另一种方法是使用getDerivedStateFromProps并添加某种计时器,以便在一段时间后将状态推送到父组件。.但是不确定这是否会使JS代码更快。所以没有尝试。
    再次更新
    javascript - React Native:具有状态和AsyncStorage的TextInput-LMLPHP
    我开源了整个代码,因为当代码如此嵌套时,很难在SO帖子中提供所有所需的信息。
    整个代码在这里:
    https://github.com/Norfeldt/LionFood_FrontEnd
    (我知道我的代码可能看起来很凌乱,但我仍在学习。)
    我不希望人们介入并使用PR修复我的代码(尽管那会很棒),但只是给我一些有关如何正确处理stateAsyncStorageTextInput的代码指导。
    我知道我有一些样式问题-希望修复它们,但也要遵守SO并保持其主题不变。
    更新二
    我删除了forceUpdate,仅用vanilla react native FadeImage替换了Image
    但我仍然看到一些奇怪的问题
    javascript - React Native:具有状态和AsyncStorage的TextInput-LMLPHP
    这是我的代码
    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上看不到相同的模拟器
    设备)“==>不正确,请稍等TextInput会扩展。
  • 状态和AsyncStorage没有任何问题。我没有得到任何警告。

  • 根本问题是FadeImage 中的动画:
  • 该应用程序呈现许多Carousel,每个Carousel都有AngleInvestorFadeImage。问题是FadeImage
  • FadeImage以持续时间1000运行Animated => CPU过载
    ==>为什么TextInput添加滚动然后花很长时间扩展,而FlatList看起来却有问题,但是没有。它们只是慢慢更新。

  • 解:
  • 尝试注释FadeImage,您将看到问题消失了。
  • 不要同时播放太多动画。只要显示就开始(例如:Carousel 中的第一张卡片)

  • 更新
    我遇到了您的问题:快速键入导致setState调用多次
    您可以在这种情况下使用can 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

    07-28 01:06