React Recoil useRecoilValue возвращает пустой атом

#reactjs #recoiljs

#reactjs #recoiljs

Вопрос:

У меня проблема с получением значения из глобального атома. У меня есть index.js routes.js а затем в компонентах у меня есть домашняя страница и страница коллажа. Домашняя страница представляет собой список имен собак и изображение каждого из них. Пользователь выберет dog, а затем atom получит это значение. Все это отлично работает на домашней странице. Однако, когда я вызываю getRecoilValue для атома со страницы collage, вызов продолжает возвращать пустой атом.

Атомы / селектор сохраняются и экспортируются в atoms.js

Корень отдачи находится в index.js . И, как я уже сказал, Recoil отлично работает на домашней странице. Почему это не работает на странице Collages?

index.js

 import React from "react";
import ReactDOM from "react-dom";
import { RecoilRoot } from "recoil";
import "./index.css";
import { BrowserRouter } from "react-router-dom";
import Routes from './routes';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render((
  <React.StrictMode>
    <RecoilRoot>
   <BrowserRouter>
    <Routes/>
  </BrowserRouter>
    </RecoilRoot>
  </React.StrictMode>
   
 ), document.getElementById('root'));
registerServiceWorker();
  

routes.js

 import React from 'react';
import { Route, Switch } from 'react-router-dom'
import Home from './components/Home';
import About from './components/about';
import Contact from './components/Contact';
import SMS from './components/SMS';
import Collages from './components/Collages';

const Routes = () => (
 
        <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/about" component={About} />  
            <Route exact path="/email" component={Contact}/>  
            <Route exact path="/text" component={SMS}/>  
            <Route exact path="/collages" component={Collages}/>       
        </Switch>
       
);    

export default Routes
  

Home.js

 import React from "react";
import { atom, useRecoilState, selector, useRecoilValue } from "recoil";
import Gracie from "../assets/gracie.png";
import Archie from "../assets/archie.png";
import Onyx from "../assets/onyx.png";
import Hulk from "../assets/hulk.png";
import Martha from "../assets/martha.png";
import Charlie from "../assets/charlie.png";
import BernieImg from "../assets/hulk.png";
import "./Home.css";
import ParticlesBg from "particles-bg";
import { Container } from "@material-ui/core";
import NavMenu from "./Menu";
import Collage from "./Collages";
import {activeDogAtom, activeLogoAtom } from "./atoms";

const DOGS = [
  "Gracie",
  "Archie",
  "Onyx",
  "Hulk",
  "Martha",
  "Charlie",
  "Bernie",
];


const Home= () => {
    const [activeDog, setActiveDog] = useRecoilState(activeDogAtom);
    const [activeLogo, setActiveImage] = useRecoilState(activeLogoAtom);

   const doggy = useRecoilValue(activeDogAtom);
   if (doggy === '' ){
     setActiveDog(DOGS[0]);
     setActiveImage(Gracie)
   };

  const handleDogUpdate = (event) => {
    const strDog = event.target.textContent;
    
    setActiveDog(strDog);

    switch (strDog) {
      case "Bernie":
        setActiveImage(BernieImg);
        break;
      case "Gracie":
        setActiveImage(Gracie);
        break;
      case "Hulk":
        setActiveImage(Hulk);
        break;
      case "Onyx":
        setActiveImage(Onyx);
        break;
      case "Martha":
        setActiveImage(Martha);
        break;
      case "Archie":
        setActiveImage(Archie);
        break;
      case "Charlie":
        setActiveImage(Charlie);
        break;
      default:
        setActiveImage(Gracie);
    }
  };

  

  return (
    <>
      <NavMenu />
      <ParticlesBg type="circle" bg={true} />
      <section>
        <h1>Knight's Kennel </h1>
        <img
          className="logo"
          src={activeLogo}
          alt="doggy"
          width="220"
          height="250"
        />
       
      </section>
      <section>
        {DOGS.map((dog) => (
          <button
            className={`btn ${dog === activeDog ? "selected" : ""}`}
            onClick={handleDogUpdate}
            key={dog}
          >
            {dog}
          </button>
        ))}
      </section>
 <p>
          🐶 Welcome! Please view images of{" "}
          <a href="/collages">
            {" "}
            <span className="dog">{activeDog}</span>{" "}
          </a>
          🐶
        </p>
      <Container>
        <h2>
          Breeders of high quality AKC Miniature Schnauzers in Rhode Island
        </h2>
      </Container>
    </>
  );
}

export default Home;
  

Collage.js

 mport * as React from "react";
import { render } from "react-dom";
import { Container } from "@material-ui/core";
import ParticlesBg from "particles-bg";
import "../utils/collagestyles.css";
import { ReactPhotoCollage } from "react-photo-collage";
import NavMenu from "./Menu";
import { atom, useRecoilState, selector, useRecoilValue } from "recoil";
import { activeDogAtom } from "./atoms";


const DOGS = [
  "Martha",
  "Archie",
  "Onyx",
  "Hulk",
  "Charlie",
  "Bernie",
  "Gracie",
];

const archieImages = ["one", "two", "three"];
const marthaImages = [
  { src: "https://1966.imgix.net/Archie_Pedigree_Sire.jpg" },
  { src: "https://1966.imgix.net/archie-head.jpg" }, ];
const bernieImages = ["one", "two", "three"];
const onyxImages = ["one", "two", "three"];
const hulkImages = [{ src: "https://1966.imgix.net/DSC01848.jpg" }];
const gracieImages = [
  { src: "https://1966.imgix.net/DSC01838.jpg" },
  { src: "https://1966.imgix.net/DSC01796.jpg" },
  { src: "https://1966.imgix.net/Archie_Pedigree_Sire.jpg" },
];


  var setting = {
    width: "300px",
    height: ["250px", "170px"],
    layout: [1, 3],
    photos: [],
    showNumOfRemainingPhotos: true,
  };

const Collages = () => {

  
  const adog = useRecoilValue(activeDogAtom);
  var dog = "";
  if(adog === ''){
    dog = DOGS[0];
    setting.photos = marthaImages;
  } else {

  switch (dog) {
    case DOGS[0]:
      setting.photos = marthaImages;
      break;
    case DOGS[1]:
      setting.photos = marthaImages;
      break;
    case DOGS[2]:
      setting.photos = hulkImages;
      break;
    case DOGS[3]:
      setting.photos = archieImages;
      break;
    case DOGS[4]:
      setting.photos = onyxImages;
      break;
    case DOGS[5]:
      setting.photos = gracieImages;
      break;
  };
  };

  return (
    <>
      <NavMenu />
      <ParticlesBg type="circle" margin="20px" bg={true} />
      <br></br>
      <Container align="center">
        <h1>Knight's Kennel</h1>

        <h2> The value of dog is  {dog} </h2>
        <h2>
          {" "}
          Breeders of high quality AKC Miniature Schnauzers in Rhode Island
        </h2>
        <section>
          <ReactPhotoCollage {...setting} />
        </section>
      </Container>
    </>
  );
};
export default Collages;
  

atoms.js

 import { atom } from "recoil";



export const activeDogAtom = atom({
  key: "activeDog",
  default: "",
});

export const activeLogoAtom = atom({
  key: "activeLogo",
  default: '',
});
  

Ответ №1:

Попробуйте изменить эту часть кода в Collage.js

 const adog = useRecoilValue(activeDogAtom);
var dog = "";
if(adog === ''){
  

к этому:

 const adog = useRecoilValue(activeDogAtom);
var dog = adog;
if(adog === ''){
  

Ответ №2:

Ответом на эту проблему была замена href компонентом Link.

   <a href="/collages">
        {" "}
        <span className="dog">{activeDog}</span>{" "}
      </a>
  

Для:

     <Link to={'/collages' }><span className="dog">{activeDog}</span></Link>{" "}