주 모험: 나의 첫 번째 프로젝트

나는 마침내 두 번째 단계의 편강을 완성했다.모든 단계가 끝날 때처럼, 우리는 지금까지 배운 모든 지식을 포함하는 프로젝트를 만들어야 한다.마지막 단계에서 자바스크립트와 API를 포함하는 프로젝트를 만들었습니다. (보실 수 있습니다.)이 단계에서 나는 어떻게 React 프레임워크를 사용하는지 배웠다.

프로젝트에서 사용한 내용

  • 반응 프레임

  • The National Park Service API 국립공원 정보 획득에 사용

  • Weatherstack API 각 국립공원
  • 의 현재 날씨를 입력하는 데 사용
  • 구글맵 API는 각 국립공원의 캠프를 표시하는 데 사용
  • 본 프로젝트는 JSON 서버를 사용하여 각 국립공원을 구제합니다
  • 단일 페이지 애플리케이션
  • 에서 탐색
  • 내 응용 프로그램의 재료 인터페이스를 설계
  • 프로젝트 개요


    대유행 기간 동안, 모든 것이 닫히기 시작했을 때, 나는 대자연 속에서 더 많은 시간을 보내는 것에 흥미를 가지기 시작했다.나는 줄곧 더 많은 국립공원에 가고 싶었지만 어디서부터 시작해야 할지 모르겠다.이 문제를 해결하기 위해 State Adventures 애플리케이션을 만들었습니다. 주 별로 국립공원을 검색하고 공원 개요를 보며 캠핑장을 볼 수 있습니다.

    주별로 국립공원을 보다


    - 애플리케이션이 로드되면 국립공원 API 자동 호출을 요청하고 사용자를 위한 4개의 무작위 국립공원을 생성합니다.이것은 폼을 사용하기 전에 내용을 채울 수 있도록 합니다.

    //snippet of home component
     export class Home extends Component {
       state = {
           selectedParks: [],
           selectedState: null,
           defaultParks: [],
       }
    
       componentDidMount() {
           //fetch default parks
           fetch(`https://developer.nps.gov/api/v1/parks?api_key=${apiKey}&limit=50`)
           .then(response => response.json())
           .then(json => {
               const newArray = []
               for(let i = 0; i < 4; i++) {
                   newArray.push(json.data[Math.floor(Math.random()*json.data.length)])
               }
               this.setState({
               defaultParks: newArray,
               })
    
           })
       }
    
    - 응용 프로그램의 영웅은 보려는 상태를 선택할 수 있는 관리 양식을 포함합니다.양식을 제출하면 상태가 콜백 함수를 통해 상위 어셈블리로 다시 전송되어 국립공원 API에 다른 요청을 보냅니다.국립공원마다 카드가 있고 선택한 주가 페이지 제목에 추가됩니다.

    //controlled form component
    export class Form extends Component {
       state = {
           stateAbbreviations: [
               'AL','AK','AS','AZ','AR','CA','CO','CT','DE','DC','FM','FL','GA',
               'GU','HI','ID','IL','IN','IA','KS','KY','LA','ME','MH','MD','MA',
               'MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND',
               'MP','OH','OK','OR','PW','PA','PR','RI','SC','SD','TN','TX','UT',
               'VT','VI','VA','WA','WV','WI','WY'
              ],
              selectedState: ""
       }
    
       handleChange = (event) => {
           this.setState({
               [event.target.name]: event.target.value
           })
       }
    
       handleSubmit = (event) => {
           event.preventDefault()
           this.props.fetchingParks(this.state.selectedState)
       }
    
    
       render() {
           return (
               <form className="hero-form" onSubmit={this.handleSubmit}>
                   <ButtonGroup>
                       <FormControl variant="outlined" color="secondary">
                           <InputLabel id="select-state">Select State</InputLabel>
                           <Select
                           labelId="select-state"
                           name="selectedState"
                           value={this.state.selectedState}
                           onChange={this.handleChange}
                           >
                               {
                               this.state.stateAbbreviations.map(state => (
                                   <MenuItem value={state} key={state}>{state}</MenuItem>
                               ))
                               }
                           </Select>
                       </FormControl>
    
                       <Button
                       type="submit"
                       variant="contained"
                       color="primary"
                       size="large"
                       >
                           Find Parks
                       </Button>
                   </ButtonGroup>
               </form>
           )
       }
    }
    
    //snippet of fetching Parks API from home component
    fetchParksApi = (stateAbbr = null) => {
           //fetch parks by state
           fetch(`https://developer.nps.gov/api/v1/parks?stateCode=${stateAbbr}=&api_key=${apiKey}`)
           .then(response => response.json())
           .then(json => {
             this.setState({
               selectedParks: json.data,
               selectedState: stateAbbr
             })
    
           })
         }
    

    국립공원 상세 정보 참조


    - "공원 보기"를 클릭하면 국립공원에 대한 개요 페이지로 안내됩니다.공원, 공원 시간, 공원 방향, 입장권, 행사와 현재 공원 날씨에 대한 정보를 볼 수 있습니다.

    - 오버뷰 구성 요소를 렌더링할 때 Weatherstack API를 API 호출하여 공원의 주소에 따라 현재 날씨를 입력합니다.페이지의 추가 정보는 국립공원관리국 API에서 제공됩니다.
    //API call for Weather
    export class ParkWeather extends Component {
       state = {
           temp: null,
           tempDetails: null
       }
    
       componentDidMount(){
           const validAddress = this.props.address.find(a => a.type === "Physical")
    
           fetch(`http://api.weatherstack.com/current?access_key=${apiKey}&units=f&query=${validAddress.postalCode}`)
           .then(res => res.json())
           .then(json => {
                this.setState({
                   temp: json.current.temperature,
                   tempDetails: json.current.weather_descriptions[0]
               })
           })
       }
    
    - 페이지의 하위 내비게이션'캠핑'링크를 클릭하여 공원의 캠핑장을 볼 수 있다.캠핑 구성 요소를 보여주면 국립공원 서비스 API를 별도로 호출해 국립공원을 캠핑장으로 끌어들이고 구성 요소 상태에 추가한다.캠프가 없으면 사용자에게 음소거 화면이 표시됩니다.

    - 캠프가 있으면 구글 맵 API가 지도에 그릴 것이다.캠프를 클릭하면 캠프 정보가 표시됩니다.캠프 설명, 시간, 비용, 예약 정책과 방향을 포함한다.

    //camping component snippet
    export class ParkCamping extends Component {
       state = {
           campgrounds: [],
           selectedCampground: null
       }
    
       componentDidMount() {
    
           fetch(`https://developer.nps.gov/api/v1/campgrounds?parkCode=${this.props.parkcode}=&api_key=${apiKey}&limit=500`)
           .then(res => res.json())
           .then(json => {
               this.setState({
                   campgrounds: json.data
               })
           })
       }
    
       handleCampgroundClick = (campground) => {
           this.setState({
               selectedCampground: campground
           })
       }
    
       handleCampgroundWindowClick = () => {
           this.setState({
               selectedCampground: null
           })
       }
       render() {
           const height = document.getElementById('park-details').offsetHeight
    
           return (
               <>
               <Grid item
               xs={12} sm={12} md={this.state.selectedCampground ? 6 : 9}
               className="details-map">
            //Google API map
                   <CampingMap
                   longitude={parseInt(this.props.longitude)}
                   latitude={parseInt(this.props.latitude)}
                   campgrounds={this.state.campgrounds}
                   selectedCampground={this.state.selectedCampground}
                   handleCampgroundClick={this.handleCampgroundClick}
                   handleCampgroundWindowClick={this.handleCampgroundWindowClick}
                    />
               </Grid>
    
               {this.state.selectedCampground && (
                   <CampingInfo
                   height={height}
                   campground={this.state.selectedCampground}/>
               )}
               </>
           )
       }
    }
    

    국립공원을 구하다


    - 국립공원 카드나 개관 페이지에서 직접 국립공원을 좋아할 수 있다.당신이 공원을 좋아할 때, 공원은 상태에 추가되어 JSON 서버에 발표됩니다. 이렇게 하면 좋아하는 공원은 전체 응용 프로그램의 변경과 갱신 과정에서 계속 존재합니다.그리고 그것은 당신의'좋아하는 공원'아래에 나타날 것입니다.

    - 심장이 다시 클릭하면 공원에서 제거, JSON 서버에서 제거, "좋아하는 공원"에 표시되지 않음

    //app component
      state = {
       savedParks: []
     }
    
    handleSaveParks = (newPark) => {
       const configData = {
         method: 'POST',
         headers: {
           'accept': 'application/json',
           'content-type': 'application/json'
         },
         body: JSON.stringify(newPark)
       }
    
       fetch('http://localhost:3000/parks', configData)
    
       this.setState(previousState => ({
         savedParks: [...previousState.savedParks, newPark]
       })
     )
     }
    
     handleUnsavePark = (removePark) => {
       const newSavedParks = this.state.savedParks.filter(park => park !== removePark)
    
       this.setState({
         savedParks: newSavedParks
       })
    
       fetch(`http://localhost:3000/parks/${removePark.id}`, {
         method: 'DELETE'
       })
     }
    
    //snippet of park card with like button
    <CardActions className="card-actions">
                       { parkIsSaved === undefined ?
                       <Tooltip title="Save Park" arrow>
                           <IconButton color="primary"
                           onClick={() => handleSaveParks(parkInfo)}
                           >
                               <FavoriteBorderIcon />
                           </IconButton>
                       </Tooltip>
                       :
                       <Tooltip title="Remove Park" arrow>
                       <IconButton color="primary"
                       onClick={() => handleUnsavePark(parkInfo)}
                       >
                           <FavoriteIcon />
                       </IconButton>
                       </Tooltip>
                       }
    
                       <Button
                       variant="text"
                       size="large"
                       color="primary"
                       endIcon={<TrendingFlatIcon />}
                       onClick={viewParkButtonClick}
                       >
                           View Park
                       </Button>
                   </CardActions>
    

    단일 페이지 애플리케이션을 사용한 탐색


    한 페이지의 응용 프로그램에 있어서, 그 묘미는 한 페이지만이 모든 요소를 채울 수 있다는 데 있다.그러나 URL을 사용하여 웹 사이트를 탐색하는 것은 허용되지 않습니다.이것이 바로 내가 React 공유기를 사용하여 React 응용 프로그램에서 내비게이션을 구축하는 데 도움을 주는 곳이다.

    - React 라우터의 내장 기록 방법push()을 사용하여 사용자가 액세스하려는 URL 경로로 안내합니다.나는 메인 네비게이션과 개관 서브 네비게이션에서 그것을 사용했다.
    - 내장된 location pathname 속성을 사용하여 사용자가 있는 페이지를 표시합니다.만약 그것이 현재 경로와 일치한다면, 나는 요소에 클래스를 추가해서 링크의 스타일을 변경할 것이다.

    - Park details 페이지에 내장된history 방법goBack()을 사용하여 사용자가 필요할 때 홈페이지로 쉽게 돌아가거나 페이지를 개관할 수 있도록 했습니다.

    마지막 생각


    React는 구조를 통해 내가 대상방향 프로그래밍(OOP)을 더욱 잘 이해할 수 있도록 도와준다.클래스 구성 요소는 필요에 따라 여러 번 사용할 수 있고 하위 구성 요소에 전달할 수 있는 속성이 있거나state라고 불리는 단일 속성을 가지고 있습니다.현재 리액트가 OOP 기능을 더 갖추고 있는지, 갈고리 기능을 더 갖추고 있는지 논란이 일고 있다.그러나 이것은 내가 학습 프레임워크를 배우기 전보다 OOP을 더 잘 이해할 수 있도록 도와준다.
    나는 React와 Material UI를 배워서 한 페이지의 응용 프로그램을 효율적으로 구축할 때 매우 즐겁게 놀았다.이것은 내가 첫 번째 프로젝트에서처럼 스타일과 기능의 상호작용에 전념하지 않고 기능을 구축하는 데 더 많은 시간을 주었다.이 구축에서 저는 React 클래스 구성 요소에 관심이 많지만 앞으로 React 기능 구성 요소와 갈고리를 이해하는 데 더 많은 시간이 걸리기를 바랍니다.

    좋은 웹페이지 즐겨찾기