为什么我的 React Native 输入字段不断重置为初始值?

问题描述 投票:0回答:3

我的 React Native 应用程序中有几个屏幕,我想在其中接收一些用户输入,但在这些屏幕上,我还想在用户第一次访问屏幕时从字段中的初始值开始,特别是当它们正在更新时现有数据。我不知道如何做到这一点,因为当我提供默认值时,输入似乎不再可编辑。在

Picker
控件上,它们会自动将自身重置为原始值,在
TextInput
字段上,它们会在短暂闪烁后将自身重置为默认值。

在事件处理程序中,我可以看到正在接收更改的值,但该数据不会传递回下拉列表,即使默认值配置为引用我在事件处理程序中更新的同一对象。

此代码重现了我所看到的问题:

import {Picker} from '@react-native-picker/picker';
// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

export default function App() {

  const scores = {
    positive: 1,
    negative: 2
  };

  const setScore = function(direction, scoreText) {
    console.log("Set "+direction+" to "+score+" currently: "+JSON.stringify(scores));
    let score = parseInt(scoreText);
    if ( direction == 'positive' ) {
      scores.positive = score;
    } else {
      scores.negative = score;
    }
  }

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph}>
        Select a different option in this dropdown and watch in astonishment as nothing happens!
      </Text>
      <Picker 
          onValueChange = { (itemValue, itemIdx) => setScore('positive', itemValue)} 
          selectedValue={scores.positive}
          >
            <Picker.Item key="1-0" label="0" value="0" />
            <Picker.Item key="1-1" label="1" value="1" />
            <Picker.Item key="1-2" label="2" value="2" />
            <Picker.Item key="1-3" label="3" value="3" />
            <Picker.Item key="1-4" label="4" value="4" />
       </Picker>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

这在工作中的小吃中可见。

我在其他地方看不到这个问题,所以这可能是我对 React Native 输入系统应该如何运行的一个根本误解。如何使用输入字段接收用户的输入,同时在屏幕首次加载时选择默认值?

react-native
3个回答
1
投票

您必须使用 useState hook 来跟踪用户可变的值,以及功能组件内任何动态更改的值。因此,不要将分数声明为

const scores = {
  positive: 1,
  negative: 2
};

我们可以使用 useState 钩子

import React, { useState } from 'react'
...
const [scores, setScores] = React.useState({
  positive: 1,
  negative: 2
})

您用初始值声明它们,它返回当前状态和更新状态的 setScores 函数,因此您可以将状态设置为

if ( direction == 'positive' ) {
  setScores({positive: score})
} else {
  setScores({negative: score})
}

1
投票

发生这种情况是因为您在 React-Native 中使用 const 来显示值(我想说,这不是 React 方式)。为什么不使用

useState
变量。比如:

const [value, setValue] = useState({ positive: 1, negative: 2});

然后当您需要设置它们时只需调用:

setValue({positive: score});
setValue({negative: score});

这里您的代码已修改。


0
投票

在 React 中,有受控输入和非受控输入。

使用不受控制的输入,您无法自己管理状态。在网络上,浏览器管理该输入的状态。对于不受控制的输入,如果您需要,请指定

defaultValue
,并且不要传递
value

通过受控输入,您可以使用

useState
或其他此类机制自行管理状态。对于受控输入,不要传递
defaultValue
,而将当前状态传递为
value
。如果您想要默认值,请将状态默认为您想要的默认值 (
useState("my default")
),或者在传递 prop 时回退到默认值(例如
value={value || "my default"}
)。

TextInput

's 
defaultValue
 prop
React Native 文档目前是这么说的:

提供一个初始值,当用户开始输入时该值将会改变。对于您不想处理监听事件和更新 value 属性以保持受控状态同步的用例很有用。

我想大多数人都会同意,这听起来很糟糕,就像它可以管理自己的状态一样。那么为什么你会看到它自行重置呢?嗯,看起来 React Native 的输入的内置状态并不是特别可靠,并且在树重新渲染时可能会丢失。例如,当我的

TextInput
onBlur
事件处理程序导致树上的状态发生变化,从而导致重新渲染时,我就会看到这种情况发生。我的结论是,在 React Native 中不依赖不受控制的输入。

© www.soinside.com 2019 - 2024. All rights reserved.