Home > Blockchain >  Pass information from an input to another component in another file
Pass information from an input to another component in another file

Time:06-22

I'm having a problem, it's been a few days, I'm studying about React and Typescript and I'm developing a temperature application, I'm stopped in a part, where I want the user to click on the submit form, the information that was typed in the input is passed to another component.

Follow my two codes below

CityWeatherSearch.tsx

import { MagnifyingGlass } from 'phosphor-react'
import { FormEvent, useCallback, useRef, useState } from 'react';
import * as Styled from './style'   


export function  CityWeatherSearch(){   

    const inputRef = useRef<HTMLInputElement>(null);
    const [city,setCity] = useState('');

    function handleClick(event:FormEvent) {
        event.preventDefault();
        const inputCity = inputRef?.current?.value;
        console.log({
            inputCity, city
        });
    }
    
    return(
        <>
            <Styled.BoxSearchCity>
                <div className="headerSearch">
                    <form>
                        <input type="text" placeholder='Procurar Cidade...' ref={inputRef} onChange={
                            event => setCity(event.target.value)} />
                        <button type="submit" onClick={handleClick}>
                            <MagnifyingGlass/>
                        </button>
                    </form>
                </div>
                <div className="bodySearch">
                    {city}
                </div>
            </Styled.BoxSearchCity>
        </>
    )
}

MainWeatherLive.tsx

import {Clock} from 'phosphor-react'
import { useFetch } from '../../GetData/useFetch'
import * as Styled from './style'



type DataWeather = {               
    name: string,    
    condition:{
        text:string,
        icon:string
    },
    temp_c:number,
    hour:[{
        temp_c:number,
        time:string,
        condition:{
            text:string,
            icon:string
        }
    }]

}


export function MainWeatherLive(){
    const {dataLocation: dataWeatherApi, isFetching, dataCurrent:dataCurrentApi, dataForecast:forecastApi}
     = useFetch<DataWeather>('/v1/forecast.json?key=aff6fe0e7f5d4f3fa0611008221406&q=Guarulhos?days=1&aqi=no&alerts=no');      
    return(
        <>
            <Styled.HeaderBox>
                <h6>Weather Now</h6>                
            </Styled.HeaderBox>
            <Styled.Container>    
                {isFetching && 
                    <p>Carregando...</p>
                }            
                <div className="mainInformation">
                    <div className="temperatura">
                        <span>{dataCurrentApi?.temp_c}º</span>
                    </div>
                    <div>
                        A cidade é {cityName}
                    </div>
                    <div className="boxCidade">
                        <div className="cidade">
                            <span>{dataWeatherApi?.name}</span>
                        </div>
                        <div className="tempoHoras">
                            <span>
                            {new Date().toLocaleTimeString('pt-BR',{hour12:false, hour:'numeric',minute:'numeric'})} - {new Date().toLocaleDateString()}
                            </span>
                        </div>
                    </div>                    
                    <div className="iconeTem">
                        <img src={dataCurrentApi?.condition.icon} alt={dataCurrentApi?.condition.text} />                        
                    </div>
                </div>
                <div className="footerBox">
                    <div className="headerFooter">
                        <Clock/> 
                        <span>Horários</span>
                    </div>
                    <div className="listaHorarios">
                        <ul className="boxTT">
                            {
                                forecastApi?.hour?.map(weatherA =>{
                                    const hourTemp = weatherA.time.split(" ")[1].replace(":00","");
                                    const hourTempNumber:number =  hourTemp;                                    
                                    const hourNow = new Date().getHours();
                                    return(   
                                        <>
                                        {
                                            hourTempNumber == hourNow &&
                                            <li>
                                                <div className="titulo" key={weatherA.temp_c}>
                                                    <span>{hourTempNumber}</span>
                                                </div>
                                                <div className="temperatura">
                                                    <img src={weatherA.condition.icon} alt={weatherA.condition.text} />
                                                    <span>{dataCurrentApi?.temp_c}º</span>
                                                </div>
                                            </li>
                                        } 
                                        
                                        {
                                            hourTempNumber > hourNow &&
                                            <li>
                                                <div className="titulo" key={weatherA.temp_c}>
                                                    <span>{hourTempNumber}</span>
                                                </div>
                                                <div className="temperatura">
                                                    <img src={weatherA.condition.icon} alt={weatherA.condition.text} />
                                                    <span>{weatherA.temp_c}º</span>
                                                </div>
                                            </li>
                                        }  
                                        </>                                        
                                        )
                                })
                            }
                        </ul>
                    </div>
                </div>
            </Styled.Container>
        </>
    )
}

Weather.tsx

import { CityWeatherSearch } from "./WeatherC/CityWeatherSearch";
import { MainWeatherLive } from "./WeatherC/MainWeatherLive";
import { WeatherDetails } from "./WeatherC/WeatherDetails";
import coldImage from '../assets/cold.jpg'
import sunImage from '../assets/sun.jpg'
import rainImage from '../assets/rain.jpg'
import nightVideo from '../assets/night.mp4'
import night from '../assets/night.jpg'


export const TypesWeather = {
    NIGHT:{
        video:{
            source: nightVideo
        },
        image:{
            source: night
        }
    },
    OVERCAST:{
        video:{
            source: nightVideo
        },
        image:{
            source: night
        }
    },
    COLD:{
        image:{
            source: coldImage,
            title: 'Frio'
        }
    },
    SUN:{
        image:{
            source: sunImage,
            title: 'Verão'
        }
    },
    RAIN:{
        image:{
            source: rainImage,
            title: 'Chuva'
        }
    },
};

export type TypesWeatherV2 = keyof typeof TypesWeather;



export function Weather(){
    return (
           <>
            <div className="globalSite" style={{background:`linear-gradient(to bottom,rgba(0,0,0,.85) 0,rgba(0,0,0,.85) 100%),url(${TypesWeather.RAIN.image.source})`}}>
            </div>
            <div className="boxAllWeather">
                <div className="backgroundWeather" style={{backgroundImage:`url(${TypesWeather.RAIN.image.source})`}}></div>
                <div className="boxAllInff">                    
                    <div className="mainWeather">                
                        <MainWeatherLive />
                    </div>
                    <div className="otherInfoWeather">
                        <CityWeatherSearch />
                        <WeatherDetails />
                    </div>
                </div>
            </div>    
           </>    

    )
}

I want to pass the city typed in CityWeatherSearch.tsx to MainWeatherLive.tsx. Where is the space 'A cidade é {cityName}' reserved, I've tried everything, but I haven't been able to, could you help me?

CodePudding user response:

You can do this in several ways:

  1. parent -> child : use props
  2. child -> parent : use callback/event emitter
  3. no direct relationship : consider using state management tool like redux

CodePudding user response:

Just lift your state uo to the parent component and pass if to the cild components as props:

function WeatherPage() {
  const [city,setCity] = useState('');
  return (
    <>
      <CityWeatherSearch city={city} setCity={setCity}/>
      //...
      <MainWeatherLive city={city}/>
      //...
    </>
  )
}

function CityWeatherSearch({city, setCity}) {
   // your code here, only without const [city, setCity] useState()
}

function MainWeatherLive({city}) {
   // your code here, now you can access city
}

If your two components don't have a direct common parent and you don't want to pass down city and setCity through a deep component hierarchy, think about using useContext to share state within your application.

  • Related