我的 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 输入系统应该如何运行的一个根本误解。如何使用输入字段接收用户的输入,同时在屏幕首次加载时选择默认值?
您必须使用 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})
}
发生这种情况是因为您在 React-Native 中使用 const 来显示值(我想说,这不是 React 方式)。为什么不使用
useState
变量。比如:
const [value, setValue] = useState({ positive: 1, negative: 2});
然后当您需要设置它们时只需调用:
setValue({positive: score});
setValue({negative: score});
这里您的代码已修改。
在 React 中,有受控输入和非受控输入。
使用不受控制的输入,您无法自己管理状态。在网络上,浏览器管理该输入的状态。对于不受控制的输入,如果您需要,请指定
defaultValue
,并且不要传递 value
。
通过受控输入,您可以使用
useState
或其他此类机制自行管理状态。对于受控输入,不要传递 defaultValue
,而将当前状态传递为 value
。如果您想要默认值,请将状态默认为您想要的默认值 (useState("my default")
),或者在传递 prop 时回退到默认值(例如 value={value || "my default"}
)。
's
defaultValue
prop的 React Native 文档目前是这么说的:
提供一个初始值,当用户开始输入时该值将会改变。对于您不想处理监听事件和更新 value 属性以保持受控状态同步的用例很有用。
我想大多数人都会同意,这听起来很糟糕,就像它可以管理自己的状态一样。那么为什么你会看到它自行重置呢?嗯,看起来 React Native 的输入的内置状态并不是特别可靠,并且在树重新渲染时可能会丢失。例如,当我的
TextInput
的 onBlur
事件处理程序导致树上的状态发生变化,从而导致重新渲染时,我就会看到这种情况发生。我的结论是,在 React Native 中不依赖不受控制的输入。