JS, React, fetch запрос вне componentDidMount

94
11 июля 2021, 17:50

Научился пользоваться fetch в рамках события componentDidMount, все работает.

componentDidMount() { 
  this.updateWindowDimensions(); 
  window.addEventListener('resize', this.updateWindowDimensions); 
   
  fetch('https://ipapi.co/json/') 
  .then(response => response.json()) 
  .then(data => this.setState({ 
    center: [data.latitude, data.longitude] 
  })); 
};

Но реакт не разрешает такое в других ивентах, например:

 updateCenter(e, country) { 
    e.preventDefault(); 
    const link = 'https://restcountries.eu/rest/v2/name/' + country + '?fullText=true'; 
    fetch(link) 
    .then(response => response.json()) 
    .then(data => this.setState({ 
      center: [data.latitude, data.longitude] 
    })); 
  };

Получаю ошибку:

Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://fb.me/react-controlled-components

Хотелось бы как-нибудь воспользоваться данными из запроса в рамках event'а. Знает кто-нибудь как это сделать?

Render()

render() { 
    return ( 
      <div> 
        <div> 
          <NavBar onSubmit={this.updateCenter} /> 
        </div> 
        <div> 
          <Map  
            center={this.state.center} 
            zoom={this.state.zoom}  
            height={this.state.height - 70}  
            width={this.state.width}  
          /> 
        </div> 
      </div> 
    ); 
  };

Answer 1

Запроcы должны делаться перед render. Так как нужно время для его получения и затем обработки. в componentDidMount(). Вызывайте в нем метод, либо смотрите ЖЦ React

Answer 2

Input в дочернем компоненте был контролируемым. Когда ссылка обработчика события onSubmit родительского компонента передавалась в дочерний, React принимал это как изменение состояния.

В родительском компоненте код не менял.

Код дочернего компонента, корректный:

export default function NavBar(props) { 
    const classes = useStyle(); 
    let _searchInput = React.createRef(); 
 
    return( 
        <div className={classes.root}> 
            <AppBar position="static" className={classes.appbar}> 
                <Toolbar> 
                    <form onSubmit={(e) => props.onSubmit(e, _searchInput.ownerDocument.activeElement.value)}> 
                        <div className={classes.search}> 
                            <div className={classes.searchIcon}> 
                                <SearchIcon /> 
                            </div> 
                            <InputBase 
                                placeholder="search" 
                                inputProps={{ 'aria-label': 'search'}} 
                                classes={{ 
                                    root: classes.inputRoot, 
                                    input: classes.inputInput, 
                                }} 
                                name='search' 
                                ref={ input => _searchInput = input }  
                            /> 
                        </div> 
                    </form> 
                </Toolbar> 
            </AppBar> 
        </div> 
    ); 
};

Полезные ссылки:

https://reactjs.org/docs/uncontrolled-components.html

https://scotch.io/tutorials/5-most-common-dropdown-use-cases-solved-with-react-downshift

Answer 3

В componentWillMont создай переменую например this.unmont = false;

componentWillMont(){
    this.unmount = false;
}
 componentWillUnmont(){
    this.unmont = true;
}

И когда хочешь сделать setstate после запроса проверь this.unmont чтобы было ровно false Пример

updateCenter(e, country) {
    e.preventDefault();
    const link = 'https://restcountries.eu/rest/v2/name/' + country + '?fullText=true';
    fetch(link)
    .then(response => response.json())
    .then(data => 
      if(!this.unmont){
         this.setState({
         center: [data.latitude]             
    })
}
);
  };
READ ALSO
javascript, получить значение поля

javascript, получить значение поля

Подскажите как получить значение поля описанного следующим образом:

107
Передача данных в comboBox

Передача данных в comboBox

С помощью combobox пытаюсь изменять размер изображениеДелаю это вот таким образом

125