从许多相同的儿童组成部分中检索状态值



我有一个包含许多相同CustomSlider组件的屏幕。我想从每个滑块中检索滑块值。

在React Native中这样做的最佳实践是什么?

这是一个最低的工作示例,有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>
    );
  }
}

不需要复杂的解决方案。我处理的方式是管理父组件中的状态。CustomSlider确实不需要知道其状态。由于父组件需要知道滑块的状态,因此最好在那里处理它。

因此,由于父组件要处理状态,这意味着我们需要对您正在做的事情进行一些更改。

  1. 在每个滑块状态的母体组件中设置初始值。这很重要,这意味着即使用户不触摸滑块,我们知道它们的值。
  2. 将功能传递给每个滑块,以回电给父部件。
  3. 作为父组件控制状态,我们可以从CustomSlider删除状态。这给出了一些选项,我们可以将其保留为Component,将其更改为 PureComponent或向更改为Functional 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需要知道其状态,因为它做的不仅仅是捕获滑块的值,则可以通过将其用作ComponentPureComponent轻松添加状态。


小吃

这是一个零食,显示上述代码工作。我已经显示了所有三个可能的组件,并在App.js中使用了它们。它们的外观没有太大的差异,但是您的用例将确定您使用的哪一个。https://snack.expo.io/@andypandy/multisliders


最佳实践

最好的做法是获得您可以找到的最简单解决方案。理想情况下,这将是Functional Component,然后是PureComponent,最后是Component。考虑国家将在哪里以及如何使用国家也很重要。我问自己的一些问题是:

  • 组件真的需要知道自己的状态吗?
  • 我打算在哪里使用该状态?
  • 我需要多长时间?
  • 我需要坚持这个状态吗?
  • 根据我当前正在使用的东西,我可以使用哪些工具?
  • 我真的需要添加另一个依赖或更多以使这项工作吗?

如果您需要应用程序中多个位置的滑块值,则可以使用react-native提供的某些功能或导航来传递这些值。Redux和MOBX在复杂性方面是很大的间接费用,只有在需要全球状态管理系统的情况下,就可以真正使用,在大多数情况下可以避免它们。

您可以通过给出每个孩子的某些键动态存储状态,并通过您给它的键访问每个状态。

一种方法是将闭合从父组件传递到 CustomSlider s作为props并监视更改。

<CustomSlider idx={n} 
              theClosurePassedThrough= (n, values) => {
// update the parents states here accordingly
              }
>

然后在适当的时间调用此关闭。

multiSliderValuesChange = values => {
  this.setState({multiSliderValue: values});
  this.props.theClosurePassedThrough(this.props.idx, values);
};

最好的做法是使用mobx或redux。

相关内容

  • 没有找到相关文章

最新更新