4
votes

Mon composant React ne se met pas à jour dans le navigateur Safari

Je pensais que tout allait bien. Fonctionne parfaitement dans Chrome, FF, Edge, même IE 11!

Le composant parent détient tout l'état. Je passe l'objet de paris au composant enfant qui calcule un décompte à transmettre au composant petit-enfant à afficher.

L'état parent «paris» est un objet avec les clés comme identifiant et la valeur comme objet.

L'état parent change correctement lorsque j'interagis avec l'application. Pourquoi seul Safari ne se met-il pas à jour lorsque l'état du parent change? (sur iOS et MacOS)

Parent

class GrandChildComponent extends React.Component {
    render() {
        const { count } = this.props;
        return (
            <div>
                <div>
                    {count > 0 && <div>{count}</div>}
                </div>
            </div>
        );
    }
}

Enfant

getBadgeCount = (league) => {
    const bets = this.props.bets;
    let count = 0;
    Object.keys(bets).map((bet) => bets[bet].event.league === league && count++);
    return count;
};

// ...

<ChildItem count={this.getBadgeCount(league)} />

Petit-enfant

class ParentComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            bets: {}
        };
    }
}

Je console.log le nombre à l'intérieur du rendu petit-enfant et dans le componentDidUpdate et il montre le bon nombre. Y a-t-il quelque chose de spécifique à Apple / Safari avec react qui me manque?


2 commentaires

Votre code semble correct. Comment mettez-vous à jour l'état dans le ParentComponent ? Utilisez-vous this.setState ou autre chose?


Oui, j'utilise this.setState ({bets: currentBets}) dans un gestionnaire de clics


5 Réponses :


1
votes

J'ai donc résolu le problème très bizarre après quelques jours.

Ce qui se passait, c'est que je suppose que le moteur du navigateur Safari ne restituait pas correctement l'icône du petit badge. J'imprimais la valeur à l'intérieur du DOM, À L'EXTÉRIEUR du badge stylisé que j'utilisais, et le numéro se mettrait à jour comme prévu ... me faisant croire que le problème était lié aux styles.

PUIS après la suppression ce que je pensais être le CSS à l'origine du problème, j'ai remarqué qu'il semblait que safari mettait `` partiellement '' à jour la valeur du badge. Il semble avoir été rendu à moitié et le numéro précédent entre en collision avec la nouvelle valeur ... Vous ne savez pas s'il s'agit d'un problème obscur avec le moteur de rendu?

 entrez la description de l'image ici

Après avoir ajouté et supprimé tous les CSS un par un, le problème est resté alors j'ai décidé de tromper le navigateur pour `` forcer '' le rendu avec un simple calcul à l'intérieur du petit-enfant où il était rendu:

const safariRenderHack = { opacity: count % 2 ? 1 : 0.99 };

<div style={safariRenderHack}>{count}</div>

 entrez la description de l'image ici

Ce n'est pas une excellente solution mais bon, je suppose que c'est corrigé. ha


0 commentaires

2
votes

Dans le cas où des variables sont modifiées en fonction desquelles vous pouvez basculer entre les styles (opacité: 1 ou opacité: 0,99), vous pouvez essayer d'ajouter une clé à l'élément qui n'est pas mis à jour dans Safari / iOS.

/ p>

{Count}

J'ai rencontré le même problème, cela semble fonctionner pour le moment.


0 commentaires

0
votes

Je viens de rencontrer un problème similaire. Safari n'a pas rendu à nouveau certains textes implémentés comme:

<span>{someValue}</span>

Lors de la mise à jour du champ 'someValue', reactJS a bien fonctionné (l'élément a été rendu nécessaire) mais Safari ne restitue que la zone de nouvelle valeur (plus court que le précédent). Problèmes d'interface utilisateur: - /

Si j'ai fait quelque chose à CSS via les outils de développement, l'élément a été rendu à nouveau et semble bien: - /

Après quelques essais, j'ai heureusement utilisé un 'display: block;' propriété de style et il commence à re-rendu absolument parfait. De plus, 'display: inline-block;' résoudra également ce problème, s'il est nécessaire de l'utiliser.


0 commentaires

0
votes

cela peut vous aider:

va changer: transformer;


2 commentaires

la question a été posée il y a un an et demi


@Lukianchuk Maxim Si vous pensez que cette question vieille de 18 mois a besoin d'une meilleure réponse (ce qui en soi est parfaitement bien), veuillez expliquer exactement quoi et pourquoi vous suggérez ce code. Vous voudrez peut-être lire ce stackoverflow.com/help/how-to-answer



1
votes

J'ai eu un problème similaire où un span positionné au centre utilisant flexbox à l'intérieur d'un div ne se mettait pas à jour correctement dans Safari.

Restyling ce div pour utiliser display: block a résolu ce problème de rendu donc cela pourrait valoir la peine d'être examiné si quelqu'un rencontre le même problème à l'avenir.

PS En regardant le code de style maintenant, faire le changement était en fait une solution beaucoup plus propre car cela réduisait le nombre de lignes de 4 à 1, mais cela pourrait ne pas être le cas pour tous les scénarios bien sûr.

avant:

text-align: center;

après: (est un div donc display: le bloc est déjà utilisé)

display: flex;
flex-direction: row;
justify-content: center;
align-items: center;


0 commentaires