Повторное отображение состояния после установки состояния - PullRequest
0 голосов
/ 25 марта 2019

Я хочу получить данные, и если я получаю ошибку при получении. Я хочу подождать 1000 секунд, и при получении данных снова.

Проблема в том, что в методе settingTimeout () this.setState ({timerStatus: true}); Я ожидаю перерисовки всего приложения и рендеринга тайм-аута в console.log. Но по какой-то причине он этого не сделал. Я пытался использовать в settingTimeout () this.forceUpdate (); без особой удачи. Реагирует аналогично примеру

this.state = {
      retryTimer: 1000,
      timerStatus: false,
    }
  }
  componentDidMount(){
    if(this.state.timerStatus){
      console.log('timeout');
    }
    this.newGame();
  }

  newGame =() => {
    Axios.get(
      this.state.apiBase + 'nexGame',
      this.state.headers
    )
    .then(response =>{
     console.log(response)
      }
    })
    .catch(error =>{
      this.settingTimeout();
    })
  }
  settingTimeout = () =>{
    this.setState({timerStatus: true});
    if(this.state.retryTimer === 0){
      this.newGame();
    }
  }

Ответы [ 2 ]

0 голосов
/ 25 марта 2019

Вы можете попробовать что-то вроде следующего (объяснение находится под скрипкой):

let counter = 0;

class App extends React.Component {
    timer;
    
    constructor(props) {
        super(props);
        
        this.state = {
            data: "",
            loading: true,
            fetchError: false            
        }
    }
    
    componentDidMount() {
        /* Simulating a fetch with setTimeout. */
        const random = Math.floor(Math.random() * 1000) + 100;
        
        setTimeout(() => {
            /* Here you would write .then(). */
            if (counter === 2) {
                this.setState({loading: false});
            }
            
            /* Here you would write .catch(). */
            if (counter === 0) {
                this.setState({fetchError: true});
                this.timer = setInterval(this.handleFetch, 1000);
            }
            
            counter++;
        }, random);
    }
    
    handleFetch = () => {
        /* Simulating a fetch with setTimeout. */
        const random = Math.floor(Math.random() * 1000) + 100;
        setTimeout(() => {
            /* This would be the then(), where you save the data. */
            if (counter === 2) {
                clearInterval(this.timer);
                this.setState({loading: false, fetchError: false, data: "YES!!"})
            }
            
            /* In this case, if the fetch fails, you do nothing. */
                                  
            counter++;
        }, random);
    }
    
    render() {
        const {fetchError, loading, data} =  this.state;
        return (
            <React.Fragment>
                {loading && fetchError && <p>Error in Fetch</p>}
                {loading && !fetchError && <p>Loading</p>}
                {!loading && !fetchError && <p>{this.state.data}</p>}
           </React.Fragment>
        );
    }
}

ReactDOM.render(<App />, document.getElementById('root'));
@import url(https://fonts.googleapis.com/css?family=Montserrat);

body {
    font-family: 'Montserrat', sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id='root'></div>

Во-первых, я использую setTimeout для имитации выборок. Кроме того, чтобы смоделировать ошибку выборки, я использую переменную counter: когда она достигает значения 2, выборка считается правильной, в противном случае она считается неудачной.
Сказал, что происходит? В componentDidMount вы запускаете свою первую выборку: вместо if (counter === 2) вы должны записать .then() своей выборки (то есть, когда она работает правильно). В этом обратном вызове вы можете просто установить this.state.loading на false.
В противном случае вместо if (counter === 0) вы должны написать оператор catch(): здесь вы создаете interval, вызывая функцию handleFetch() каждые 1000ms. Обратите внимание, что в этом случае вы устанавливаете this.state.fetchError на true: таким образом вы можете улучшить обратную связь с пользователем.

Теперь внутри handleFetch() вы выполняете выборку: опять же, если она заканчивается правильно, вы можете установить this.state.loading и this.state.fetchError на false и сохранить данные в состоянии. В противном случае вы просто ждете следующего 1000ms следующего извлечения.

0 голосов
/ 25 марта 2019

похоже, что вы хотите сделать еще один вызов каждые 1, если предыдущий не удался, верно?

Я не уверен, что для этого вам нужно перерисовать приложение. Если вы хотите переделать этот вызов, вы можете использовать жизненный цикл реакции с компонентом https://reactjs.org/docs/react-component.html#updating

с:

shouldComponentUpdate(nextProps, nextState) {
  if(this.nextState.timerStatus = true) { 
    setState({ timerStatus: false });
    this.newGame();
}

И установите тайм-аут в вашей функции settingTimeout, когда пройдет 1 с, измените состояние timerStatus на true. React будет наблюдать за этим, вернет значение timerStatus в значение false и переделает вызов. Если вызов в порядке, у вас будет свой ответ, если нет, вы снова подождите 1с и переделаете вызов и т. Д. И т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...