J'ai écrit une version personnalisée de material-ui TextField (appelons-le CustTextField1) avec un style personnalisé. Je souhaite développer une autre personnalisation appelée CustTextField2 basée sur le style de CustTextField1. J'ai appliqué InputProps à CustTextField1 et je veux que ceux-ci soient utilisés dans CustTextField2 avec quelques InputProps supplémentaires que j'applique là. Voici les parties pertinentes du code. Les InputProps appliqués à CustTextField2 apparaissent (c'est-à-dire l'icône en forme d'œil de mot de passe) mais semblent remplacer les InputProps déjà définis dans CustTextField1. Toute aide sur la façon de combiner les deux serait très appréciée.
function CustTextField2(props) { return ( <CustTextField1 InputProps={{ endAdornment: ( <InputAdornment position="end"> <IconButton> {showPassword ? <Visibility/> : <VisibilityOff/>} </IconButton> </InputAdornment> ), ...props.InputProps } }} {...props} /> ) }
function CustTextField1(props) { return ( <TextField InputProps={{ disableUnderline: true, classes: { root: textFieldStyle.rootInputStyle, focused: textFieldStyle.focused, disabled: textFieldStyle.disabled, error: textFieldStyle.error } }} {...props} /> ) }
J'aimerais que le style InputProps dans CustTextField1 soit combiné avec le style InputProps supplémentaire dans CustTextField2 .
!! MISE À JOUR !!
Code Sandbox (problème d'origine) - https://codesandbox.io/s/fervent-smoke-g8nsb
Code Sandbox (Solution) avec nos sincères remerciements pour le message de toutpt ci-dessous - https: // codesandbox. io / s / stoïque-mclean-9kh1r
3 Réponses :
Vous devez toujours vous occuper de la composition lorsque vous souhaitez hériter. Vous devez donc d'abord vous occuper des accessoires que vous souhaitez remplacer.
Dans l'exemple suivant, CustTextField1 s'occupera d'InputProps pour ajouter la base et laisser l'utilisateur les remplacer.
Mais comme il y a les classes
qui sont aussi un objet, je dois m'en occuper.
InputProps={} // the one define by CustTextField1 ... InputProps={} // the one define by CustTextField2
Dans votre exemple, vous ne déstructurez pas les accessoires Ainsi, lorsque vous étendez les accessoires, vous remplacez complètement InputProps
.
InputProps={} {...props}
Donc, si props
contient InputProps code> vous le faites deux fois:
function CustTextField1({ InputProps, ...props }) { const iprops = Object.assign({ disableUnderline: true, }, InputProps, { classes: Object.assign({ root: textFieldStyle.rootInputStyle, focused: textFieldStyle.focused, disabled: textFieldStyle.disabled, error: textFieldStyle.error, }, InputProps.classes || {}) }); return <TextField InputProps={iprops} {...props} />; }
Exemple de codesandbox utilisant votre solution: codesandbox.io/s/stoic-mclean-9kh1r
Oui ça l'a fait. Merci beaucoup.
Excellent ! veuillez valider la réponse en utilisant le bouton cocher sous le vote dans ce cas;)
Pardon. Réponse validée maintenant :)
Vous déclarez deux fois les mêmes accessoires, donc les derniers appliqués écraseront les précédents. Si vous vous donnez déjà la peine de créer 2 composants séparés, il serait plus judicieux de commencer le 2ème à partir de zéro sans utiliser le premier.
Cependant, je pense qu'une meilleure solution consiste à utiliser un seul composant et à ajouter un accessoire pour basculer la configuration supplémentaire souhaitée:
function CustTextField(props) { let inputProps = { disableUnderline: true, classes: { root: textFieldStyle.rootInputStyle, focused: textFieldStyle.focused, disabled: textFieldStyle.disabled, error: textFieldStyle.error }, endAdornment: props.adornment ? ( <InputAdornment position="end"> <IconButton> {true ? <Visibility /> : <VisibilityOff />}</IconButton> </InputAdornment> ) : null }; return <TextField InputProps={inputProps} {...props} />; } .... <CustTextField adorned={true}/>
L'injection Prop dans React fonctionne de manière similaire à la façon dont les objets Javascript sont gérés, c'est-à-dire que la clé correspondante suivante remplace la clé précédente. Dans le contexte de l'objet, ce que vous faites est de remplacer les InputProps
par les InputProps
provenant de this.props
. pour votre cas d'utilisation spécifique, vous remplacez chaque accessoire en plaçant {... this.props}
avant de combiner InputProps
dans CustTextField2
.
function CustTextField2(props) { return ( <CustTextField1 {...props} InputProps={{ endAdornment: ( <InputAdornment position="end"> <IconButton> {showPassword ? <Visibility/> : <VisibilityOff/>} </IconButton> </InputAdornment> ), ...props.InputProps } }} /> ) }
de cette façon, vous passerez tous les accessoires avec le prop InputProps
remplacé à votre goût.
Cela fait passer les InputProps de CustTextField1 mais l'endAdornment n'est pas ajouté. C'est donc mon problème initial, mais maintenant l'inverse.