1
votes

Récupérer les valeurs d'état de plusieurs des mêmes composants enfants React native

J'ai un écran qui contient plusieurs des mêmes composants CustomSlider . J'aimerais récupérer les valeurs des curseurs de chaque curseur.

Quelle est la meilleure pratique pour faire cela dans react native?

Voici un exemple de travail minimum, avec 3 curseurs:

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>
    );
  }
}


0 commentaires

3 Réponses :


0
votes

Vous pouvez stocker l'état dynamiquement par une clé donnée à chaque enfant, et accéder à chacun d'eux par la clé que vous lui donnez.


0 commentaires

0
votes

Une façon est de transmettre une fermeture du composant parent aux CustomSlider comme accessoires et de surveiller les changements.

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

Appelez ensuite cette fermeture au moment opportun.

/ p>

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

La meilleure pratique consiste cependant à utiliser MobX ou Redux.


0 commentaires

2
votes

Aucune solution complexe n'est nécessaire. La façon dont je gérerais cela est de gérer l'état dans le composant parent. Le CustomSlider n'a pas vraiment besoin de connaître son état. Comme le composant parent a besoin de connaître l'état des curseurs, il est préférable de le gérer ici.

Donc, comme le composant parent va gérer l'état, cela signifie que nous devons apporter des modifications à ce que vous faites. p>

  1. Définissez les valeurs initiales dans le composant parent pour l'état de chacun des curseurs. C'est important, cela signifie que même si l'utilisateur ne touche pas les curseurs, nous connaissons leurs valeurs.
  2. Passez une fonction à chacun des curseurs qui rappelle le composant parent.
  3. Comme le composant parent contrôle l'état, nous pouvons supprimer l'état du CustomSlider . Cela donne quelques options que nous pourrions le laisser en tant que Component , le changer en PureComponent ou aller encore plus loin et le changer en un Functional Component code > Si le curseur n'a pas vraiment besoin de connaître son état, la dernière option devrait être la meilleure pour les performances.

Voici comment je refactoriserais votre App.js

const CustomSlider = ({intialValues, onChange}) => {
  return (
     <MultiSlider
        values={intialValues}
        onValuesChange={onChange}
        min={0}
        max={10}
        step={1}
      />
  )
}

Remarquez que nous n'avons pas réellement besoin une fonction pour obtenir les valeurs des curseurs tels qu'ils sont stockés dans l'état. Cela signifie que nous pouvons accéder directement aux valeurs des curseurs en utilisant this.state.sliderValues.


Voici votre CustomComponent refactorisé pour fonctionner avec le code ci-dessus:

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}
      />
    )
  }

Remarquez qu'il n'a pas du tout besoin de gérer l'état car le composant parent le gère. Cela signifie également que nous pouvons supprimer beaucoup de code qui n'est pas réellement nécessaire. C'est pourquoi je pense que nous pouvons aller plus loin et en faire un Composant Fonctionnel

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>
    );
  }
}

Si toutefois le CustomSlider code > a besoin de connaître son état car il fait quelque chose de plus que de capturer les valeurs du curseur, vous pouvez facilement y ajouter un état en l'utilisant comme Component ou comme PureComponent .


Snack

Voici une collation montrant le fonctionnement du code ci-dessus. J'ai montré les trois composants possibles et les ai utilisés dans App.js . Il n'y a pas beaucoup de différence dans leur apparence, mais votre cas d'utilisation déterminera celui que vous utilisez. https://snack.expo.io/@andypandy/multisliders

Bonnes pratiques

La meilleure pratique consiste à opter pour la solution la plus simple que vous puissiez trouver. Idéalement, ce serait un composant fonctionnel , puis un PureComponent et enfin un composant . Il est également important de se demander où et comment l'État va être utilisé. Certaines questions que je me pose sont:

  • Un composant a-t-il vraiment besoin de connaître son propre état?
  • Où ai-je l'intention d'utiliser cet état?
  • Pendant combien de temps ai-je besoin de ces valeurs d'état?
  • Dois-je conserver cet état?
  • Quels sont les outils dont je dispose en fonction de ce que j'utilise actuellement?
  • Ai-je vraiment besoin d'ajouter une ou plusieurs dépendances pour que cela fonctionne?

Si vous avez besoin des valeurs des curseurs à plusieurs endroits de votre application, vous pouvez utiliser certaines des fonctionnalités fournies par react-native ou votre navigation pour transmettre ces valeurs . Redux et MobX sont de gros frais généraux en termes de complexité et ne devraient vraiment être utilisés que si vous avez besoin d'un système de gestion d'état global, dans la majorité des cas, ils peuvent être évités.


0 commentaires