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> ); } }
3 Réponses :
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.
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.
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>
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
.
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
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:
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.