1
votes

réagir aux crochets, impossible de mettre à jour l'état via les accessoires

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


2 commentaires

Je pense que vous devriez essayer comme ceci: setVisible (false)


@SouvikGhosh a toujours eu un problème


3 Réponses :


2
votes

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 de props.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])


5 commentaires

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?



0
votes

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)


0 commentaires

0
votes

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


4 commentaires

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 à mais appmodal.js l'a répertorié comme AppModal - peut-être modifier le code pour y faire référence correctement?


c'est juste un alias