0
votes

L'instruction Switch-case détruit les composants rendus

J'ai le problème suivant: j'utilise le package nba-react-logos et cela fonctionne bien, jusqu'à ce que j'essaie de déterminer quel composant doit être retourné. Voici mon composant qui détermine quel composant du package doit être rendu:

(8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0:
homeTeam: "Golden State Warriors"
homeTeamAbbreviation: "GSW"
homeTeamScore: 100
visitorTeam: "Boston Celtics"
visitorTeamAbbreviation: "BOS"
visitorTeamScore: 105
__proto__: Object
1:
homeTeam: "Los Angeles Lakers"
homeTeamAbbreviation: "LAL"
homeTeamScore: 99
visitorTeam: "Sacramento Kings"
visitorTeamAbbreviation: "SAC"
visitorTeamScore: 97
__proto__: Object
2:
homeTeam: "Minnesota Timberwolves"
homeTeamAbbreviation: "MIN"
homeTeamScore: 116
visitorTeam: "Washington Wizards"
visitorTeamAbbreviation: "WAS"
visitorTeamScore: 137
__proto__: Object
3:
homeTeam: "Houston Rockets"
homeTeamAbbreviation: "HOU"
homeTeamScore: 111
visitorTeam: "Indiana Pacers"
visitorTeamAbbreviation: "IND"
visitorTeamScore: 102
__proto__: Object
4:
homeTeam: "Orlando Magic"
homeTeamAbbreviation: "ORL"
homeTeamScore: 111
visitorTeam: "San Antonio Spurs"
visitorTeamAbbreviation: "SAS"
visitorTeamScore: 109
__proto__: Object
5:
homeTeam: "Oklahoma City Thunder"
homeTeamAbbreviation: "OKC"
homeTeamScore: 127
visitorTeam: "Philadelphia 76ers"
visitorTeamAbbreviation: "PHI"
visitorTeamScore: 119
__proto__: Object
6:
homeTeam: "Memphis Grizzlies"
homeTeamAbbreviation: "MEM"
homeTeamScore: 107
visitorTeam: "Utah Jazz"
visitorTeamAbbreviation: "UTA"
visitorTeamScore: 106
__proto__: Object
7:
homeTeam: "Charlotte Hornets"
homeTeamAbbreviation: "CHA"
homeTeamScore: 109
visitorTeam: "Detroit Pistons"
visitorTeamAbbreviation: "DET"
visitorTeamScore: 106

Il existe également un composant fonctionnel, qui est utilisé dans mon application:

    export default function TeamScoreBox(props) {
    return (
        <div className="mainScoreBarTeam">
            <PickTeam team={props.teamAbbreviation} size={100}/> 
        </div>
    );
}

Le problème est que si je veux rendre ces composants dans de nombreux composants sur la même page, je perds des couleurs. Je ne sais pas si le problème vient de mon code ou peut-être de ce package. Je peux voir que si je les rend en composant, ils semblent bons pendant 1 à 2 secondes, jusqu'à ce que mon composant basé sur la requête http se charge - alors cette disparition de couleur apparaît.

ÉDITER

Ok, alors voici une description plus précise. J'ai le code suivant:

C'est un composant qui détermine quel logo d'équipe doit être rendu. Les accessoires sont générés à partir de la requête axios sur mon serveur.

    export default function Score(props) {
    const [game, setGame] = useState(props.gameData);

    return (
        <Card className="mainScoreBarItem">
            <Row className="align-items-center h-100">
                <Col >
                    <TeamScoreBox
                        teamName={game.homeTeam}
                        teamAbbreviation={game.homeTeamAbbreviation}
                    />
                </Col>
                <Col >
                    <div className="mainScoreBarResult">{game.homeTeamScore}:{game.visitorTeamScore}</div>
                </Col>
                <Col>
                    <TeamScoreBox
                        teamName={game.visitorTeam}
                        teamAbbreviation={game.visitorTeamAbbreviation}
                    />
                </Col>
            </Row>

        </Card>
    )
}

Le suivant est juste pour le test, c'est HomeComponent, et il est rendu sans aucune demande:

    export default function Scores() {
    const [matches, setMatches] = useState([]);
    const [loading, setLoading] = useState(true);
    useEffect(() => {
        setLoading(true)
        axios({
            method: 'GET',
            url: 'https://localhost:44324/apidata/todaygames',
            headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS',
            },
        }).then((res) => {
            
            setMatches(res.data);
            setLoading(false);
        }).catch((error) => {
            console.log(error);
        });
    }, []);

    
        return !loading 
        ?
        (
            <Row className="mainScoreBar">
                {matches.map((key) => {
                    return (
                        <Col key={key.homeTeam + key.visitorTeam} sm={4} style={{ display: "inline-block" }}>
                            <Score gameData={key} />
                        </Col>
                    );
                })}
            </Row>
        )
        : <Loading />
}

Et maintenant, voici les résultats:

  1. 1-2 premières secondes après l'actualisation de la page

  2. Après avoir obtenu les données dans la barre de jeux (en haut)

Et c'est ce avec quoi j'ai un problème. Comme vous pouvez le voir, par exemple, le logo Boston Celtics (le vert) perd sa couleur noire, les 76ers (logo avec sept rouges et six bleus) perdent leur couleur rouge.

MODIFIER v2

J'ai fait quelques corrections comme @emi l'a suggéré, mais cela n'a pas aidé.

Il y a donc le code complet de mes composants:

App.js:

    export default function App() {
  return (
    <div className="background">
      <ContextProvider>
        <Router>
          <Navigation />
          <Scores />
          <div className="content">
            <Route exact path="/" component={Home} />
            <Route path="/login" component={Login} />
            <Route path="/register" component={Register} />
            <Route path="/players/:id" exact={true} component={PlayerStats} />
            <Route path="/players" exact={true} component = {Players} />
            <ProtectedRoute path='/logout' />
          </div>
        </Router>
      </ContextProvider>
    </div>
  );
}

Sur chaque page, j'ai la navigation et les scores, alors passez au composant Scores:

Scores.js:

    export const Home = () => {
    return (
        <div><Logos.BOS></Logos.BOS><Logos.PHX></Logos.PHX><Logos.BOS></Logos.BOS><Logos.PHI></Logos.PHI><Logos.PHI></Logos.PHI>
        <PickTeam team={"PHI"} size={100}/></div>
    );
}

Score.js:

    export default function TeamScoreBox(props) {
    return (
        <div className="mainScoreBarTeam">
            <PickTeam team={props.teamAbbreviation} size={100}/> 
        </div>
    );
}

Et TeamScoreBox.js:

export default function PickTeam({team, size}) {
    const Found = Constants.TEAMS_LOGOS[team];
    return Found ? <Found size={size} /> : <div />;
}

Ainsi, la route "/" doit afficher la navigation, les scores et (mentionné dans la première édition) le contrôleur Home.

Ma réponse axios:

    export const TEAMS_LOGOS = {
    [TEAM_76ERS]: Logos.PHI,
    [TEAM_RAPTORS]: Logos.TOR,
    [TEAM_TIMBERWOLVES]: Logos.MIN,
    [TEAM_BUCKS]: Logos.MIL,
    [TEAM_HORNETS]: Logos.CHA,
    [TEAM_NUGGETS]: Logos.DEN,
    [TEAM_PISTONS]: Logos.DET,
    [TEAM_MAGIC]: Logos.ORL,
    [TEAM_PELICANS]: Logos.NOP,
    [TEAM_LAKERS]: Logos.LAL,
    [TEAM_THUNDER]: Logos.OKC,
    [TEAM_MAVERICKS]: Logos.DAL,
    [TEAM_KINGS]: Logos.SAC,
    [TEAM_BLAZERS]: Logos.POR,
    [TEAM_JAZZ]: Logos.UTA,
    [TEAM_HAWKS]: Logos.ATL,
    [TEAM_WARRIORS]: Logos.GSW,
    [TEAM_SUNS]: Logos.PHX,
    [TEAM_NETS]: Logos.BKN,
    [TEAM_KNICKS]: Logos.NYK,
    [TEAM_WIZARDS]: Logos.WAS,
    [TEAM_SPURS]: Logos.SAS,
    [TEAM_BULLS]: Logos.CHI,
    [TEAM_CELTICS]: Logos.BOS,
    [TEAM_ROCKETS]: Logos.HOU,
    [TEAM_PACERS]: Logos.IND,
    [TEAM_CLIPPERS]: Logos.LAC,
    [TEAM_CAVALIERS]: Logos.CLE,
    [TEAM_GRIZZLIES]: Logos.MEM,
    [TEAM_HEAT]: Logos.MIA
}


3 commentaires

Pour rendre votre code plus propre (et probablement plus efficace si vous créez le tableau en dehors de la fonction, ou lorsqu'il est optimisé par le moteur JS), votre gros code de bloc switch/case peut être changé en un tableau associatif: const relations = {[Constants.TEAM_76ERS]: Logos.PHI, ....}; const Found = relations[team]; return Found ? <Found size={size} /> : <div/>


Sur la base du code que vous avez fourni, il n'y a rien qui change les couleurs nulle part, même aucune couleur n'est changée ou affichée du tout. Je pense que vous devrez reformuler votre question pour obtenir de l'aide.


@emi J'ai mis à jour mon message, donc j'espère que mon problème est maintenant plus clair.


3 Réponses :


1
votes

Votre OtherFunctions.pickTeam peut être écrit en tant que composant fonctionnel:

export const Home = () => {
  return (
    <div>
      <Logos.BOS/><Logos.PHX/><Logos.BOS/><Logos.PHI/><Logos.PHI/>
      <OtherFunctions.PickTeam team={"PHI"} size={100} /> 
    </div>
  );
}

Ensuite, vous l'utilisez comme n'importe quel autre composant:

export default function TeamScoreBox(props) {
  return (
    <div className="mainScoreBarTeam">
      <OtherFunctions.PickTeam team={props.teamAbbreviation} size={100} /> 
    </div>
  );
}

Et votre composant Home , en utilisant le nouveau PickTeam et en simplifiant les composants sans enfants:

const relations = {
  [Constants.TEAM_76ERS]: Logos.PHI,
  // etc...
};
export function PickTeam({team, size}) {
  const Found = relations[team];
  return Found ? <Found size={size} /> : <div/>
}

Cela augmentera les performances, la lisibilité et la maintenabilité.

Votre problème de couleurs est toujours indépendant du code que vous avez affiché dans votre question, mais peut bénéficier des exemples publiés dans cette réponse. S'il vous plaît, testez-le et, s'il ne fonctionne toujours pas, ajoutez du code pertinent pendant et autour de l'appel AXIOS, ce qui ressemble à certaines classes / statuts / accessoires y sont gérés. Aussi, le cas échéant, publiez ce que votre serveur répond à cette demande.


2 commentaires

Je l'ai fait et cela n'a pas résolu mon problème. J'ai mis à jour le message une fois de plus.


Votre question fait toujours référence à l'ancienne version dans les 3 premiers blocs de code. Veuillez le modifier pour éviter de confondre les nouveaux arrivants (ou nous-mêmes à l'avenir).



1
votes

La logique de loading ne semble pas correcte: vous devez attribuer true juste avant la fetch et affecter false à la finale then :

    // Invert condition
    return !loading
         ? (
            <Row className="mainScoreBar">
                {matches.map((key) => {
                    return (
                        <Col key={key.homeTeam + key.visitorTeam} sm={4} style={{ display: "inline-block" }}>
                            <Score gameData={key} />
                        </Col>
                    );
                })}
            </Row>
         )
         : <Loading/>

Éditer

Votre logique de loading est toujours boguée: vous voulez afficher les données pendant le chargement, et afficher <Loading/> quand ce n'est pas le cas. Essayez ceci, qui utilise l'opérateur ternaire:

    useEffect(() => {
        setLoading(true);
        axios({
            method: 'GET',
            url: 'https://localhost:44324/apidata/todaygames',
            headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS',
            },
        }).then((res) => {
            setMatches(res.data);
            setLoading(false);
        }).catch((error) => {
            console.log(error);
        });
    }, []);


4 commentaires

Ça ne change rien.


Avez-vous d'autres conseils?


Édité avec une correction supplémentaire pour la logique de loading


Oui, j'ai oublié de le changer ici, mais cela n'a pas d'importance - si je supprime toutes les fonctionnalités de "chargement" - je rencontre le même problème. J'ai aussi la même situation dans le composant avec la liste des joueurs, mais il y a une situation, lorsque je filtre mes résultats, les logos commencent à s'afficher correctement. Mais il y a une condition: les composants Scores doivent être désactivés. Je pense qu'il y a quelque chose à voir avec ce choix de composants Logos ...



1
votes

J'ai jeté un coup d'œil au code source de nba-react-logos . Il utilise SVG directement à partir de React et utilise parfois des ID SVG. J'ai vu au moins une référence non existante et plusieurs définitions avec le même identifiant sur les logos. Si cela peut être un problème, mais fonctionne toujours sur le rendu initial, nous pouvons minimiser les erreurs en mémorisant le composant:

      <defs>
        <path id="A" d="M0 0h93.554v104H0z" />
        <path id="B" d="M0 0h93.554v104H0z" />
        <path
          id="C"
          d="M93.554 48.9c0-12.494-..."
        />
      </defs>
      <g transform="translate(25 20)" fill="none" fillRule="evenodd">
        <path
          d="M99.87 52.054c0-13.33-..."
          fill="#fefefe"
        />
        <g transform="translate(3 3)">
          <mask id="D" fill="#fff">
            <use xlinkHref="#A" />
          </mask>
          <use xlinkHref="#C" fill="#fff" mask="url(#D)" />
          <mask id="E" fill="#fff">
            <use xlinkHref="#B" />
          </mask>
          <use xlinkHref="#C" fill="#061922" mask="url(#E)" />
        </g>

Éditer

Exemple de code SVG étrange / non optimisé dans nba-react-logos react nba-react-logos :

export default React.memo(function PickTeam({team, size}) {
    const Found = Constants.TEAMS_LOGOS[team];
    return Found ? <Found size={size} /> : <div />;
})
  • #A et #B sont exactement les mêmes, donc #D et #E sont également exactement les mêmes. Donc, la première use dans ce g est chevauchée par la seconde. De plus, ces identifiants sont également utilisés dans d'autres logos.

Afin de déboguer ceci (ne faites jamais cela pour réparer les choses!), Pouvez-vous éditer manuellement votre code source ./node_modules/nba-react-logos et modifier les ID, afin qu'ils soient uniques dans tout le document? Par exemple, remplacez id="A" par id="A_BOS" et "#A" par "#A_BOS" (et la même chose pour B , C , D et E ).

Une fois modifiés, assurez-vous que les changements sont affichés dans votre page rendue et voyez si cela corrige ce logo. Si c'est le cas, vous pouvez compléter le rapport de bogue que vous avez ouvert là - bas , même avec une pull request si vous remplissez confortablement (et pour éviter d'attendre que l'auteur réponde en utilisant votre propre copie du dépôt au lieu de l'officiel).


5 commentaires

Non, toujours rien. J'ai peur de devoir trouver autre chose pour faire ce logos, car je n'en connais vraiment pas la raison.


Ajout d'une autre façon d'essayer de déboguer cela.


Finalement! Semble être la bonne réponse. J'ai remplacé les identifiants dans certains logos (en particulier ceux qui étaient buggés) et cela fonctionne pour le moment. Vraiment aprici votre aide et merci pour votre temps! :)


De rien! N'oubliez pas de compléter le rapport de bogue et les relations publiques pour vous aider et aider les autres!


@axern S'il vous plaît, votez également la réponse;)