essayant de mettre à jour la variable d'état ('visible') via la fonction interne (setVisible) dans le composant. J'ai vérifié le tutorÄ ± al et j'ai fait de même mais il ne s'est pas mis à jour après l'initialisation de l'état. Lien Sandobx ici .
props.visible est vrai lorsque l'utilisateur cliquez sur le bouton ShowModal. mais la valeur de visible dans le composant de fonction est toujours fausse. (J'ai vérifié le contenu sur le débogueur)
code:
const AppModal = (props) => { const [visible, setVisible] = useState(props.visible) useEffect(() =>{ setVisible(props.visible) },[props.visible]) debugger return ( <Modal visible={visible} fade={true} onClickBackdrop={props.onClickBackdrop}> <div className="modal-header"> <h5 className="modal-title">{props.title}</h5> </div> <div className="modal-body"> {props.body} </div> <div className="modal-footer"> <React.Fragment> <button type="button" className="btn btn-default" onClick={()=>setVisible(false)}> Close </button> </React.Fragment> </div> </Modal> ) }
AppModal.js:
import Modal from '../Helpers/AppModal' class Streams extends Component { constructor(props) { super(props) this.state = { showModal: false } } componentDidMount() { this.props.getStreams() } showDeleteModal = (isShow) => { this.setState({ showModal: isShow }); } onClickBackdrop = () => {this.setState({ showModal: false });} render() { return ( <div> <button onClick={()=> this.showDeleteModal(true)} className="btn btn-danger">Delete</button> <Modal visible={this.state.showModal} onClickBackdrop={this.onClickBackdrop} /> </div> ) } }
3 Réponses :
L'argument passé à useState
n'est que l'état initial. Passer un prop
à cela ne signifie pas que l ' état
sera synchronisé avec les props
. Vous pouvez configurer un effet pour refléter ces changements dans votre état local.
Actuellement, votre Modal
ne voit que visible
à partir de l'état local, la modification de la valeur props
ne provoquera pas de Modal code > pour modifier
useEffect(() => { setVisible(props.visible) })
Pourquoi devrais-je utiliser des
props
au lieu deprops.visible
ici?
Le tableau de dépendances existe pour maintenir la synchronisation, vous dites react
:
"Hé, à chaque fois qu'une de ces valeurs change, exécutez cet effet."
Le problème est que React
effectue une comparaison superficielle ( Object.is
) entre les anciens et les nouveaux accessoires
, en haut de chaque render
un nouvel objet props
est généré, ce qui déclenche votre effet en premier lieu.
React ne sait pas comment "réagir" aux changements imbriqués. Ce qui change vraiment ici, ce sont les props
, react ne sait pas (et ne se soucie pas) des props.visible
, les passer en tant que dépendance équivaut à passer []
En fait, passer props
comme dépendance est inutile, puisque props
change chaque rendu, vous pouvez omettre le tableau des dépendances, ce qui déclenchera l'effet sur chaque rendu
//Inside child useEffect(() =>{ setVisible(props.visible) },[props])
quand j'ai fait cela, cela fonctionne bien pour le premier clic mais n'affiche pas le modal après la fermeture et reclique le bouton
Pouvez-vous publier un exemple dans un bac à sable? Vous n'avez pas réellement besoin de useState
ici, mais je suppose que vous voulez l'utiliser correctement?
Oui, j'ai créé un bac à sable, j'espère que cela vous aidera; codesandbox.io/embed/interesting-haze-wb2vw?fontsize=14
C'était mon erreur. J'ai passé props.visible
comme dépendance, mais vous devriez passer props
. mis à jour la réponse
btw pouvez-vous me dire pourquoi cela fonctionne, pourquoi utiliser des accessoires au lieu de probs.visible là-bas?
visible
est un booléen.
Essayez de changer la façon dont vous appelez setVisible
comme ceci:
setVisible({visible:false})
au lieu de
setVisible(false)
S'il s'agit d'un interrupteur à bascule, vous devriez faire ceci:
const [visible, setVisible] = useState(false);
Ensuite, il s'activer / désactiver correctement.
Vous voudrez peut-être définir l'initiale valeur plus explicite cependant:
onClick={() => setVisible(!visible)}
fait, mais le problème est toujours là, j'ai édité le message (AppModal.js)
FYI en le définissant sur false sur le onClick, il ne fonctionnera qu'une seule fois. C'est pourquoi j'ai suggéré de le définir initialement sur false, puis d'utiliser le drapeau! Visible dans le onClick ().
@TyForHelpDude Dans votre code, vous faites référence à
c'est juste un alias
Je pense que vous devriez essayer comme ceci:
setVisible (false)
@SouvikGhosh a toujours eu un problème