react-native - 从许多相同的子组件中检索状态值反应原生
问题描述
我有一个包含许多相同CustomSlider
组件的屏幕。我想从每个滑块中检索滑块值。
在本机反应中这样做的最佳实践是什么?
这是一个最小的工作示例,带有 3 个滑块:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import MultiSlider from "@ptomasroos/react-native-multi-slider";
class CustomSlider extends Component {
constructor(props) {
super(props)
this.state = {
multiSliderValue: [1, 9]
}
}
multiSliderValuesChange = values => {
this.setState({multiSliderValue: values});
};
render(){
return (
<MultiSlider
values={this.state.multiSliderValue}
onValuesChange={this.multiSliderValuesChange}
min={0}
max={10}
step={1}
/>
)
}
}
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
};
}
get_slider_values = () => {
// what is best practice to access the values of every slider here?
// eg an object like this
const slider_values = [[1.4, 7.4], [4.3, 7.0], [1.9, 3.2]]
return slider_values
}
render() {
return (
<View style={{alignItems: 'center', justifyContent: 'center', padding: 50}}>
<CustomSlider />
<CustomSlider />
<CustomSlider />
<Text>{`The slider values are: ` + JSON.stringify(this.get_slider_values())}</Text>
</View>
);
}
}
解决方案
不需要复杂的解决方案。我处理这个问题的方法是管理父组件中的状态。TheCustomSlider
并不真的需要知道它的状态。由于父组件需要知道滑块的状态,所以最好在那里处理它。
因此,由于父组件将处理状态,这意味着我们需要对您正在做的事情进行一些更改。
- 在父组件中为每个滑块的状态设置初始值。这很重要,这意味着即使用户没有触摸滑块,我们也知道它们的值。
- 将函数传递给回调父组件的每个滑块。
- 由于父组件控制状态,我们可以从
CustomSlider
. 这提供了一些选项,我们可以将其保留为 aComponent
,将其更改为 aPureComponent
或更进一步将其更改为 aFunctional Component
如果滑块确实不需要知道其状态,那么最后一个选项应该最适合性能。
这是我将如何重构您的App.js
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
sliderValues: [[1, 9],[1, 9],[1, 9]] // we should control the state here
};
}
// this uses function currying to bind the function and pass a value to it
onChange = (index) => (values) => {
this.setState( prevState => {
let sliderValues = prevState.sliderValues;
sliderValues[index] = values;
return {
sliderValues
}
})
}
render() {
return (
<View style={{alignItems: 'center', justifyContent: 'center', padding: 50}}>
<CustomSlider intialValues={this.state.sliderValues[0]} onChange={this.onChange(0)}/>
<CustomSlider intialValues={this.state.sliderValues[1]} onChange={this.onChange(1)}/>
<CustomSlider intialValues={this.state.sliderValues[2]} onChange={this.onChange(2)}/>
<Text>{`The slider values are: ` + JSON.stringify(this.state.sliderValues)}</Text>
</View>
);
}
}
注意我们实际上并不需要一个函数来获取滑块的值,因为它们存储在状态中。这意味着我们可以通过使用直接访问滑块的值this.state.sliderValues
。
这是您CustomComponent
为使用上述代码而进行的重构:
class CustomSlider extends Component { // this could easily be swapped for a PureComponent
render(){
return (
<MultiSlider
values={this.props.intialValues}
onValuesChange={this.props.onChange}
min={0}
max={10}
step={1}
/>
)
}
注意它根本不需要管理状态,因为父组件正在处理它。这也意味着我们可以删除很多实际上不必要的代码。这就是为什么我认为我们可以更进一步,使其成为Functional Component
const CustomSlider = ({intialValues, onChange}) => {
return (
<MultiSlider
values={intialValues}
onValuesChange={onChange}
min={0}
max={10}
step={1}
/>
)
}
但是,如果CustomSlider
需要知道它的状态,因为它所做的不仅仅是捕获滑块的值,那么您可以通过将其用作 aComponent
或 a来轻松地为其添加状态PureComponent
。
小吃
这是显示上述代码工作的小吃。我已经展示了所有三个可能的组件,并在App.js
. 它们的外观没有太大区别,但您的用例将决定您使用哪一个。https://snack.expo.io/@andypandy/multisliders
最佳实践
最佳做法是寻找您能找到的最简单的解决方案。理想情况下,这将是 a Functional Component
,然后是 a PureComponent
,最后是 a Component
。考虑将在何处以及如何使用状态也很重要。我问自己的一些问题是:
- 组件真的需要知道自己的状态吗?
- 我打算在哪里使用该状态?
- 我需要这些状态值多久?
- 我需要保持这种状态吗?
- 根据我目前使用的工具,我可以使用哪些工具?
- 我真的需要添加另一个或更多依赖项来完成这项工作吗?
如果您需要应用程序中多个位置的滑块值,您可以使用react-native
导航提供的一些功能来传递这些值。Redux 和 MobX 在复杂性方面开销很大,只有在需要全局状态管理系统时才应该真正使用,在大多数情况下可以避免它们。
推荐阅读
- python - Django/ Django_plotly_Dash(异常值:预期的字符串或类似字节的对象)
- apache-kafka - 卡卡auto.offset.reset查询
- c# - 返回表格中单元格的值 - C# - selenium Webdriver
- azure-ad-b2c - 在具有 OIDC 和 OAuth/API 访问权限的 B2C 中,我应该在哪里执行(组/角色等效)?
- azure-devops - Pulumi Azure Pipeline 任务
- python-3.x - 如何获取同时发生的事件列表
- sql - Presto - 插入数组作为函数输入
- json - 如何根据json文件中的项目数生成卡片列表
- javascript - Phaser 3:无法读取未定义的属性“$”
- python - 如何在 Graphql 突变中返回 PDF 文件?