컴포넌트의 Reactjs 비동기 렌더링


82

내 ajax 요청이 완료된 후 구성 요소를 렌더링하고 싶습니다.

아래에서 내 코드를 볼 수 있습니다.

var CategoriesSetup = React.createClass({

    render: function(){
        var rows = [];
        $.get('http://foobar.io/api/v1/listings/categories/').done(function (data) {
            $.each(data, function(index, element){
                rows.push(<OptionRow obj={element} />);
            });
           return (<Input type='select'>{rows}</Input>)

        })

    }
});

하지만 내 ajax 요청의 done 메서드 내에서 렌더링을 반환하기 때문에 아래 오류가 발생합니다.

Uncaught Error: Invariant Violation: CategoriesSetup.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

렌더링을 시작하기 전에 내 ajax 요청이 끝날 때까지 기다리는 방법이 있습니까?


3
또한, 작은 편협하지만 render () 루틴에서 데이터 검색을하는 것은 좋은 생각이 아닙니다. render ()를 렌더링하고 나머지는 추상화하십시오. 또한 구성 요소가 렌더링 될 때마다가 아니라 해당 데이터를 한 번만 가져오고 싶을 수도 있습니다.
Phil Cooper

답변:


131

이를 처리하는 방법에는 두 가지가 있으며, 데이터를 소유해야하는 구성 요소와로드 상태에 따라 선택하는 방법이 다릅니다.

  1. Ajax 요청을 부모로 이동하고 구성 요소를 조건부로 렌더링합니다.

    var Parent = React.createClass({
      getInitialState: function() {
        return { data: null };
      },
    
      componentDidMount: function() {
        $.get('http://foobar.io/api/v1/listings/categories/').done(function(data) {
          this.setState({data: data});
        }.bind(this));
      },
    
      render: function() {
        if (this.state.data) {
          return <CategoriesSetup data={this.state.data} />;
        }
    
        return <div>Loading...</div>;
      }
    });
    
  2. 컴포넌트에 Ajax 요청을 유지하고로드하는 동안 조건부로 다른 것을 렌더링합니다.

    var CategoriesSetup = React.createClass({
      getInitialState: function() {
        return { data: null };
      },
    
      componentDidMount: function() {
        $.get('http://foobar.io/api/v1/listings/categories/').done(function(data) {
          this.setState({data: data});
        }.bind(this));
      },
    
      render: function() {
        if (this.state.data) {
          return <Input type="select">{this.state.data.map(this.renderRow)}</Input>;
        }
    
        return <div>Loading...</div>;
      },
    
      renderRow: function(row) {
        return <OptionRow obj={row} />;
      }
    });
    

6
나는 2017 년 에이 답변을 우연히 발견했습니다.이 두 가지 최고의 솔루션이 여전히 사용하기에 가장 좋습니까?
Dan

@Dan React는 소품과 상태를 기반으로 UI를 렌더링하므로 핵심 개념은 동일하게 유지됩니다. Ajax 요청을 수행하고, 상태를 설정하고, 무언가를 다시 렌더링합니다. 그러나 고차 구성 요소와 같은 패턴이 더 대중화되어 복잡성을 추상화 할 수있는 방법을 보여줍니다.
미셸 틸리

1
if (this.state.data)해야 if (this.state && this.state.data)때때로 상태가 null이 될 수 있기 때문이다.
Timo

@Timo 흠, 어떤 경우에 할 this.statenull?
Michelle Tilley

6
@Timo는 생성자의 상태를 초기화합니다
Louis

8

구성 요소의 비동기 렌더링의 기본 예는 다음과 같습니다.

import React                from 'react';
import ReactDOM             from 'react-dom';        
import PropTypes            from 'prop-types';

export default class YourComponent extends React.PureComponent {
    constructor(props){
        super(props);
        this.state = {
            data: null
        }       
    }

    componentDidMount(){
        const data = {
                optPost: 'userToStat01',
                message: 'We make a research of fetch'
            };
        const endpoint = 'http://example.com/api/phpGetPost.php';       
        const setState = this.setState.bind(this);      
        fetch(endpoint, {
            method: 'POST',
            body: JSON.stringify(data)
        })
        .then((resp) => resp.json())
        .then(function(response) {
            setState({data: response.message});
        });
    }

    render(){
        return (<div>
            {this.state.data === null ? 
                <div>Loading</div>
            :
                <div>{this.state.data}</div>
            }
        </div>);
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.