카테고리 없음

React-Class Ajax

meta-tony 2023. 4. 1. 22:26

React를 통한 간단한 AJAX 코드

//fetch호출이 시작되는 public폴더에 list.json과 1, 2, 3 파일명의 json을 저장
class Nav extends Component {
  state = {
    list:[]
  }
  
  componentDidMount() {
    fetch('list.json')
      .then(function(result){
        return result.json();
      })
      .then(function(json){
        this.setState({list:json});
      }.bind(this))
  }
  
  render(){
    var listTag = [];
    for(var i=0; i<this.state.list.length; i++){
      var li = this.state.list[i];
      listTag.push(<li key={li.id}><a href={li.id}>{li.title}</a></li>)
    }
    return(
      <nav>
        <ul>
          {listTag}
        </ul>
      </nav>
    )
  }
}

data-set 참조 (kyounghwan01.github)
 


AJAX로 JSON 호출
1) 클래스의 메소드인 componentDidMount() 함수에 fetch-API를 통해 JSON 데이터 요청 (AJAX Call)
2) 응답이 완료되면 첫 번째 then 파라미터로 전달
3) 첫 번째 then은 데이터(string)를 가져왔을 때, 데이터 형식 json()함수를 통한 변환값 리턴
4) 리턴 값이 두 번째 then의 인자로 전달 
5) 인자 출력하기 위한 setState를 통한 값 입력과 배열 출력(bind)

fetch('list.json') // 서버에 파일 요청
  .then(function(result){
    return result.json(); //  응답 완료시 list.json을 문자열로 인자로 받음 => json으로 converting
  })
  .then(function(json){ // 첫번째 then의 return value => 두번째 then parameter
this.setState({list:json});// this값 undefined
  }.bind(this)); // bind함수를 통한 this값 Nav (this == window)
}
AJAX를 통한 상태 변경(Loading 창)
비동기화 구조화(decoupling)를 통해 수정이 용이한 코드 작성
- Presentation Container: 데이터를 보여주기 위한 컴포넌트(데이터 종속X) 
- Container Component 데이터가 종속되어 있는 컴포넌트

Loading 창 구현하기
1)조건문을 통해 컴포넌트 실행
2)실행 완료시 로딩 변수값 수정 (isLoading:false)
3)fetch API가 실행되기전 변수값 수정(isLoading:true) 후 복사한 컴포넌트 실행(nowLoading) 
Code
if(this.state.list.isLoading){
  NavTag =  <NowLoading></NowLoading>
}else {
  NavTag =  <Nav list={this.state.list.items} onClick={function(id){
    var newArticle = Object.assign({}, this.state.article, {isLoading:true}) //복사 후 재실행
    this.setState({article:newArticle})
    fetch(id + ".json")
      .then...코드진행

 
 

JS기능
Object.assign 

bind
React 기능
React API - setState()
- setState(): 컴포넌트 state의 변경 사항을 setState의 인자에 넣고, 변경된 state를 사용하여 렌더링 진행
- setState()는 갱신하는 데에 있어 명령이 아니라 요청

state와 props의 차이
- props는 (함수 매개변수처럼) 컴포넌트전달되는 반면state는 (함수 내에 선언된 변수처럼) 컴포넌트안에서 관리됩니다.
- setState 호출은 비동기적으로 이뤄집니다. 
- React는 브라우저 이벤트가 끝날 시점에 state를 일괄적으로 업데이트(성능 향상)
componentDidMount (React AJAX)
componentDidMount()는 컴포넌트가 마운트된 직후 호출됩니다. 
DOM 노드가 있어야 하는 초기화 작업은 이 메서드에서 이루어지면 됩니다.
외부에서 데이터를 불러와야 한다면, 네트워크 요청을 보내기 적절한 위치입니다.

componentDidMount() 메서드는 데이터 구독을 설정하기 좋은 위치입니다.
componentWillUnmount()에서 구독 해제 작업을 반드시 수행하기 바랍니다.

componentDidMount()에서 즉시 setState()를 호출하는 경우도 있습니다. 
추가적인 렌더링이 발생하지만, 브라우저가 화면을 갱신하기 전에 완료됩니다
render()가 두 번 호출되지만, 사용자는 그 중간 과정을 볼 수 없다. (다만, 성능 문제 주의) 

주로 앞의 방식을 대신하여 constructor() 메서드에서 초기 state를 할당
렌더링에 앞서 하는 경우 componentDidMount()를 사용 (DOM 노드의 크기나 위치를 먼저 측정하는 모달, 툴팁)

 완성코드

//fetch호출이 시작되는 public폴더에 list.json과 1, 2, 3 파일명의 json을 저장
import React, {Component} from 'react';

class Nav extends Component {
  render(){
    let listTag = [];
    this.props.list.map(arr => {
    return listTag.push(
        <li key={arr.id}>
        <a href={arr.id} data-id={arr.id} onClick={function(e){
          e.preventDefault();
          this.props.onClick(e.target.dataset.id)
        }.bind(this)}>
          {arr.title}
        </a>
      </li>
      )
  })
    return(
      <nav>
        <ul>
          {listTag}
        </ul>
      </nav>
    )
  }
}
class Article extends Component{
  render(){
    return(
    <article>
      <h2>{this.props.title}</h2>
      {this.props.desc}
    </article>
    )}
}
class NowLoading extends Component{
  render(){
    return <div>Now Loading...</div>
  }
}
class App extends Component {
  state = {
    article:{
      item:{title:'Welcome', desc:"Hello, React & Ajax"},
      isLoading:false
    },
    list:{
    items:[],
    isLoading:false
    }
  }

  componentDidMount() {
    let newList = Object.assign({}, this.state.list, {isLoading:true});
    this.setState({list:newList})
    fetch('list.json')
      .then(function(result){
        return result.json();
      })
      .then(function(json){
        this.setState({list:{
          items:json,
          isLoading:false
        }});
      }.bind(this))
  }
  render(){
    let NavTag = null;
if(this.state.list.isLoading){
  NavTag =  <NowLoading></NowLoading>
}else {
  NavTag =  <Nav list={this.state.list.items} onClick={function(id){
    //list contents AJAX
    let newArticle = Object.assign({}, this.state.article, {isLoading:true})
    this.setState({article:newArticle})
    fetch(id + ".json")
          .then(function(result){
            return result.json(); 
          })
        .then(function(json){
          this.setState({
            article:{
              item:{
                title:json.title, 
                desc:json.desc
            },
            isLoading:false
            }
          })
        }.bind(this))
      }.bind(this)} />
    }
  let ArticleTag = null;
  if(this.state.article.isLoading){
    ArticleTag = <NowLoading></NowLoading>
  }else{
    ArticleTag = <Article title={this.state.article.item.title} desc={this.state.article.item.desc} />
  }
  return (
    <div style={{margin:40, border:"1px solid #aaa", padding:40,paddingTop:10}}>
      <h1>Web</h1>
      {NavTag}
      {ArticleTag}
    </div>
  )};
}

export default App;

Reference 생활코딩

 

React-Ajax

 

www.youtube.com

 

 

AJAX, fetch-API, AJAX polyfill

Reference 생활코딩 AJAX 1. AJAX 자바스크립트와 연동하여 리로딩없이 페이지 및 데이터 로직 구현 (Single Page; Web Application) 최근 검색 엔진에 불리한 점이 보완된 pjax를 사용(pjax = pushState + ajax) 2. fetch

meta-tony.tistory.com