Quiero obtener los datos cuando se hace clic en el botón de búsqueda, para eso hice una función, en eso cambié el estado de los datos y luego obtuve los datos. Pero el problema está en el enlace de búsqueda que proporcioné, está tomando el valor inicial de ese estado de datos, no el valor que he cambiado después de hacer clic en el botón de búsqueda. Código:
<form className="d-flex"> <input onChange={(e) => this.setState({ instant_data: e.target.value }) } className="form-control me-2" type="search" placeholder="Search" aria-label="Search" /> <button className="btn btn-outline-success" type="submit" onClick={this.searchNews} > Search </button> </form> constructor() { super(); this.state = { instant_data: "", data: "", search_data: [], }; } searchNews = async (e) => { e.preventDefault(); this.setState({ data: this.state.instant_data, }); const link = `https://newsapi.org/v2/everything?q=${this.state.data}&apiKey=API_KEY`; const raw_data = await fetch(link); const data = await raw_data.json(); console.log(data); };De la documentación ;
setState() no muta inmediatamente
this.statesino que crea una transición de estado pendiente. Accederthis.statedespués de llamar a este método puede potencialmente devolver el valor existente. No hay garantía de funcionamiento síncrono de las llamadas a setState y las llamadas pueden agruparse por lotes para mejorar el rendimiento.
Sugerencia -> pasar una función de devolución de llamada:
this.setState({ data: this.state.instant_data, }, () => { const link = `https://newsapi.org/v2/everything?q=${this.state.data}&apiKey=API_KEY`; const raw_data = await fetch(link); const data = await raw_data.json(); console.log(data); });Esto se debe a que this.setState no es un cambio inmediato, a veces lleva algo de tiempo configurarlo, por lo que no debe usar this.state.data sino usar this.state.instant_data como:
const link = `https://newsapi.org/v2/everythingq=${this.state.instant_data}&apiKey=API_KEY`;Cambie su entrada a:
<input onChange={(e) => this.setState({ instant_data: e.target.value })} className="form-control me-2" type="search" placeholder="Search" aria-label="Search" value={this.state.instant_data} <--- added this here /> Y cambie su función de searchNews de noticias a:
searchNews = async (e) => { e.preventDefault() const link = `https://newsapi.org/v2/everything?q=${this.state.instant_data}&apiKey=API_KEY` const raw_data = await fetch(link) const data = await raw_data.json() console.log(data) }Esencia
// this is async operation this.setState({ data: this.state.instant_data, }); Entonces terminas haciendo la llamada primero y luego actualizas los data la variable de estado