首页 > 解决方案 > 反应不重新渲染状态变化?

问题描述

我目前正在渲染一个页面,其中有一堆放在单独的“卡片”中的口袋妖怪。每个口袋妖怪都可以根据状态被喜欢和不喜欢,喜欢口袋妖怪会使卡片变成粉红色,而不喜欢口袋妖怪会将卡片变回标准的灰色。

我希望在单击按钮后立即将页面或口袋妖怪卡重新渲染为正确的颜色并具有正确的收藏或取消收藏方法,但目前我必须刷新页面才能发生这种情况。目前,我的组件 Pokemon 正在由我的组件 Dashboard 渲染,其中 Dashboard 将映射出 30 个不同的 Pokemon 组件并以类似网格的方式布置它们。所以我想知道这是否可行?这是我的代码:

import React, { useState, useEffect, useContext } from 'react';
import './Pokemon.css';
import Popup from 'reactjs-popup';
import 'reactjs-popup/dist/index.css';
import UserContext from '../../context/userContext';
import { array } from 'prop-types';

import axios from 'axios';


function Pokemon(props) { // Have app.js pass in props of the jsons to here? Then render their names and pictures, and prepare if click
  const [isFav, setIsFav] = useState();
  const { userData, setUserData } = useContext(UserContext); // use userData.user.favPokemon to access the favorite pokemon
  const [error, setError] = useState();
  const [putArr, setPutArr] = useState([...userData.user.favPokemon]);
  // Can use userData.user.favPokemon.find(props.pokemon.name) to search for the pokemon. If found (i.e. not undefined)
  // then render it differently.


  useEffect(() => {
    const found = (element) => element === props.pokemon.name;
    const isFound = (userData.user.favPokemon).some(found);
    setIsFav(isFound);
    if (isFound) {
      const index = userData.user.favPokemon.indexOf(props.pokemon.name);
      const removedFav = putArr;
      removedFav.splice(index, 1);

      setPutArr(removedFav); // array we will be PATCH'ing when we want to unfavorite a pokemon (array - current pokemon)
      // putArr.splice(index, 1); 
    }
    else {
      setPutArr(putArr.concat(props.pokemon.name)); // array we will be PATCH'ing when we want to favorite a pokemon (array + current pokemon)
      // putArr.push(props.pokemon.name) 
    }
  }, [isFav])

  const id = userData.user.id;
  const favOrUnfav = async (e) => { // Patch method to favorite or unfavorite a pokemon
    e.preventDefault();
    try {
      console.log(putArr);
      const updateUser = {id, putArr};
      await axios.patch("http://localhost:5000/users/favorite", updateUser);
    } catch(err) {
      err.response.data.msg && setError(err.response.data.msg)
    }
    setIsFav(!isFav);
  };
    
  const pokeFacts = {
    imageUrl: props.pokemon.sprites.front_default,
    name: props.pokemon.name,
    ability: props.pokemon.abilities[0].ability.name,
    numberMoves: props.pokemon.moves.length,
    type: props.pokemon.types,
    stats: props.pokemon.stats
  }

  return (
    isFav === true ? 
    <div className="Pokemon-card-fav">
      <Popup trigger={<div><img className="Pokemon-card-image" src={pokeFacts.imageUrl} alt="Picture of a pokemon"></img>
      {pokeFacts.name} <button className="favButton" onClick={(e) => {favOrUnfav(e); console.log(isFav)}}>UnFavorite</button></div>} modal>
        <div>
          <p><b>Name</b>: {pokeFacts.name}</p>
          <p><b>Ability</b>: {pokeFacts.ability}</p>
          <p><b>Number of Possible Moves</b>: {pokeFacts.numberMoves}</p>
          <p><b>Type</b>: {pokeFacts.type.map((index) => (index.type.name) + " ")}</p>
          <p><b>Base Stats</b>: {pokeFacts.stats.map((index) => (index.stat.name) + ": " + (index.base_stat) + " ")}</p>
        </div>
      </Popup>
    </div>
    :
    <div className="Pokemon-card">
      <Popup trigger={<div><img className="Pokemon-card-image" src={pokeFacts.imageUrl} alt="Picture of a pokemon"></img>
      {pokeFacts.name} <button className="favButton" onClick={(e) => {favOrUnfav(e); console.log(isFav)}}>Favorite</button></div>} modal>
        <div>
          <p><b>Name</b>: {pokeFacts.name}</p>
          <p><b>Ability</b>: {pokeFacts.ability}</p>
          <p><b>Number of Possible Moves</b>: {pokeFacts.numberMoves}</p>
          <p><b>Type</b>: {pokeFacts.type.map((index) => (index.type.name) + " ")}</p>
          <p><b>Base Stats</b>: {pokeFacts.stats.map((index) => (index.stat.name) + ": " + (index.base_stat) + " ")}</p>
        </div>
      </Popup>
    </div>
  );
}

export default Pokemon;

在此处输入图像描述

标签: javascriptreactjs

解决方案


我认为您可以使用 Pokemon 道具渲染 Pokemon 组件,而无需组件中的 http 请求。

我的意思是你应该在父组件中请求并将道具传递给口袋妖怪组件。您可以在父组件中单击按钮后进行请求并将道具传递给口袋妖怪组件,因此您的组件将被重新渲染。

您可以创建 useCallback 函数,该函数在父组件中执行您的 Pokemon !favorite 并传递给 Pokemon,以便您可以使用 in 更改收藏状态。


推荐阅读