#reactjs #json
Вопрос:
Я начинаю с реакции и сталкиваюсь с проблемой неопределенного. Итак, здесь у меня есть мой контекстный файл с функцией useEffect, которая извлекает данные из файла «data.json». Внутри я также возвращаю новый массив с парами ключ-значение и обновляю состояние с помощью массива. Так что, если я хочу утешить.войдите в состояние, в котором он показывает мне массив, заполненный парами ключ-значение, о которых я упоминал выше. Но когда я хочу утешить.регистрируйте, например, первый индекс массива (состояние) с помощью, например, ключа «имя», он не знает, что такое «имя». Есть какие-нибудь предложения? Я прикрепляю файл контекста и файл data.json.
import React from "react"; import { useState, useEffect } from "react"; export const Context = React.createContext({ onChooseMoon: () =gt; {}, onChooseMars: () =gt; {}, }); const ContextProvider = (props) =gt; { const [planet, setPlanets] = useState(); useEffect(() =gt; { fetch("./data.json") .then((response) =gt; { return response.json(); }) .then((data) =gt; { const transformedData = data.destinations.map((destination) =gt; { return { name: destination.name, img: destination.images.png, desc: destination.description, dist: destination.distance, travel: destination.travel, }; }); setPlanets(transformedData); }); }, []); if (planet) { setPlanets(planet[0]); console.log("hello"); //shows hello 2 times but only in here (context file) //console.logs from component file does not show anything } const setMoonHandler = () =gt; { setPlanets(planet[0]); // return { // name: planet[0].name, // img: planet[0].img, // desc: planet[0].description, // dist: planet[0].distance, // travel: planet[0].travel, // }; }; const setMarsHandler = () =gt; { setPlanets(planet[1]); // return { // name: planet[1].name, // img: planet[1].img, // desc: planet[1].description, // dist: planet[1].distance, // travel: planet[1].travel, // }; }; return ( lt;Context.Provider value={{ planet: planet, onChooseMoon: setMoonHandler, onChooseMars: setMarsHandler, }} gt; {props.children} lt;/Context.Providergt; ); }; export default ContextProvider;
{ "destinations": [ { "name": "Moon", "images": { "png": "../assets/destination/image-moon.png", "webp": "./assets/destination/image-moon.webp" }, "description": "See our planet as you’ve never seen it before. A perfect relaxing trip away to help regain perspective and come back refreshed. While you’re there, take in some history by visiting the Luna 2 and Apollo 11 landing sites.", "distance": "384,400 km", "travel": "3 days" }, { "name": "Mars", "images": { "png": "./assets/destination/image-mars.png", "webp": "./assets/destination/image-mars.webp" }, "description": "Don’t forget to pack your hiking boots. You’ll need them to tackle Olympus Mons, the tallest planetary mountain in our solar system. It’s two and a half times the size of Everest!", "distance": "225 mil. km", "travel": "9 months" }, { "name": "Europa", "images": { "png": "./assets/destination/image-europa.png", "webp": "./assets/destination/image-europa.webp" }, "description": "The smallest of the four Galilean moons orbiting Jupiter, Europa is a winter lover’s dream. With an icy surface, it’s perfect for a bit of ice skating, curling, hockey, or simple relaxation in your snug wintery cabin.", "distance": "628 mil. km", "travel": "3 years" }, { "name": "Titan", "images": { "png": "./assets/destination/image-titan.png", "webp": "./assets/destination/image-titan.webp" }, "description": "The only moon known to have a dense atmosphere other than Earth, Titan is a home away from home (just a few hundred degrees colder!). As a bonus, you get striking views of the Rings of Saturn.", "distance": "1.6 bil. km", "travel": "7 years" } ], "crew": [ { "name": "Douglas Hurley", "images": { "png": "./assets/crew/image-douglas-hurley.png", "webp": "./assets/crew/image-douglas-hurley.webp" }, "role": "Commander", "bio": "Douglas Gerald Hurley is an American engineer, former Marine Corps pilot and former NASA astronaut. He launched into space for the third time as commander of Crew Dragon Demo-2." }, { "name": "Mark Shuttleworth", "images": { "png": "./assets/crew/image-mark-shuttleworth.png", "webp": "./assets/crew/image-mark-shuttleworth.webp" }, "role": "Mission Specialist", "bio": "Mark Richard Shuttleworth is the founder and CEO of Canonical, the company behind the Linux-based Ubuntu operating system. Shuttleworth became the first South African to travel to space as a space tourist." }, { "name": "Victor Glover", "images": { "png": "./assets/crew/image-victor-glover.png", "webp": "./assets/crew/image-victor-glover.webp" }, "role": "Pilot", "bio": "Pilot on the first operational flight of the SpaceX Crew Dragon to the International Space Station. Glover is a commander in the U.S. Navy where he pilots an F/A-18.He was a crew member of Expedition 64, and served as a station systems flight engineer." }, { "name": "Anousheh Ansari", "images": { "png": "./assets/crew/image-anousheh-ansari.png", "webp": "./assets/crew/image-anousheh-ansari.webp" }, "role": "Flight Engineer", "bio": "Anousheh Ansari is an Iranian American engineer and co-founder of Prodea Systems. Ansari was the fourth self-funded space tourist, the first self-funded woman to fly to the ISS, and the first Iranian in space." } ], "technology": [ { "name": "Launch vehicle", "images": { "portrait": "./assets/technology/image-launch-vehicle-portrait.jpg", "landscape": "./assets/technology/image-launch-vehicle-landscape.jpg" }, "description": "A launch vehicle or carrier rocket is a rocket-propelled vehicle used to carry a payload from Earth's surface to space, usually to Earth orbit or beyond. Our WEB-X carrier rocket is the most powerful in operation. Standing 150 metres tall, it's quite an awe-inspiring sight on the launch pad!" }, { "name": "Spaceport", "images": { "portrait": "./assets/technology/image-spaceport-portrait.jpg", "landscape": "./assets/technology/image-spaceport-landscape.jpg" }, "description": "A spaceport or cosmodrome is a site for launching (or receiving) spacecraft, by analogy to the seaport for ships or airport for aircraft. Based in the famous Cape Canaveral, our spaceport is ideally situated to take advantage of the Earth’s rotation for launch." }, { "name": "Space capsule", "images": { "portrait": "./assets/technology/image-space-capsule-portrait.jpg", "landscape": "./assets/technology/image-space-capsule-landscape.jpg" }, "description": "A space capsule is an often-crewed spacecraft that uses a blunt-body reentry capsule to reenter the Earth's atmosphere without wings. Our capsule is where you'll spend your time during the flight. It includes a space gym, cinema, and plenty of other activities to keep you entertained." } ] }
import Header from "../components/Header/Header"; import Planets from "../components/Planets/Planets"; import styles from "./Destination.module.css"; import ChoosePlanet from "../components/Planets/ChoosePlanet"; import { useContext } from "react"; import { Context } from "../store/context"; const Destination = () =gt; { const ctx = useContext(Context); //does not show anything, which means planet is not true if (ctx.planet) { console.log(ctx.planet[0].name); console.log(ctx.planet); console.log("planet is true"); } return ( lt;div className={styles.body}gt; lt;Header /gt; lt;h2gt; lt;spangt;01lt;/spangt;PICK YOUR DESTINATION lt;/h2gt; lt;main className={styles.main}gt; {ctx.planet amp;amp; lt;Planets img={ctx.planet.img} alt="planet" /gt;} {ctx.planet amp;amp; ( lt;ChoosePlanet name={ctx.planet.name} text={ctx.planet.desc} distance={ctx.planet.dist} time={ctx.planet.travel} /gt; )} lt;/maingt; lt;/divgt; ); }; export default Destination;
Ответ №1:
useEffect
выполняется только после первого рендеринга, поэтому при первом рендеринге ваша planet
переменная по-прежнему остается значением, которое вы использовали для ее инициализации ( true
).
Вместо этого попробуйте следующий подход: оставьте начальное значение planet
как undefined
:
// no value is the same as `undefined` when invoking a function const [planet, setPlanets] = useState();
Затем, каждый раз, когда вы используете planet
свой код, сначала убедитесь, что это не undefined
так, прежде чем пытаться использовать его / получить доступ к его свойствам:
if (planet) { // planet is not `undefined` console.log(planet[0]); // ok } else { // planet is falsy, so do something else }
Комментарии:
1. Спасибо! Это сработало.
2. Эй, ваше решение сработало, но я отказался от создания объекта для конкретного индекса в каждом setPlanetHandler. Я решил манипулировать состоянием в его собственной функции настройки (не знаю, хорошая ли это привычка), поэтому при нажатии соответствующей кнопки изменяется индекс состояния. Но теперь состояние «планета» не работает в файле компонента. Это не признается истинной ценностью. Похоже, это ложь, и я не знаю почему. Я вставил обновленные экраны в сообщение. Не могли бы вы взглянуть на это?
3. Я предлагаю опубликовать новый вопрос, когда у вас появится новый вопрос, так как на другой вопрос уже дан ответ.