Реагировать на передачу полученных данных другому компоненту

Эй!

У меня проблема с кодом реакции. Моя задача - вызвать из iTunes API, что я делаю с помощью fetch, а затем обрабатываю данные. Но я не могу сохранить его как переменную, чтобы иметь возможность передать его позже.

import React, { Component } from 'react';

class SearchField extends Component{
  constructor(props) {
  super(props);
  this.state = {value: ''};

this.handleChangeEvent = this.handleChangeEvent.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

handleChangeEvent = (event) => {
  this.setState({value: event.target.value});
}

handleSubmit = (event) => {
  event.preventDefault();
  fetch(`https://itunes.apple.com/search?media=music&term=${this.state.value.toLowerCase()}`)
  .then((resp) => resp.json())
  .then(searchRes => searchRes.results[0].artistName)
  .catch(err => console.info(err));
}

render() {
return(
  <section className = "hero is-primary">
    <div className = "hero-body">
      <div className = "container">
        <form onSubmit = {this.handleSubmit}>
          <input className = "input is-primary" type = "text" value = {this.state.value} onChange = {this.handleChangeEvent} placeholder = "Search for artist" />
          <input className = "button is-info" type = "submit" value = "Search" />
        </form>
      </div>
    </div>
  </section>
)
}
}
export default SearchField;

Мне придется использовать полученные данные позже, мне просто нужно сначала имя исполнителя. Если я регистрирую значение (searchRes.results [0] .artistName, я получаю правильное значение, но если я хочу сохранить его для последующего использования, я получил только пустой console.info. Я пробовал несколько подходов, но так и не получил результат.

Помогите мне, пожалуйста.

🤔 А знаете ли вы, что...
JavaScript имеет множество библиотек и фреймворков, таких как jQuery, Angular, и Vue.js.


3
5 128
2

Ответы:

Решено

Пожалуйста, уточните, что вы имеете в виду под

but if i want to save it for later use i only got empty console.info back

Я думаю, что правильный способ справиться с вашей проблемой - передать функцию обратного вызова реквизитам вашего компонента, которая вызывается всякий раз, когда вы нажимаете поиск и находит результат поиска, например: https://codesandbox.io/s/xpq171n1vz

Обновлено: обратите внимание, что, хотя этот ответ был принят и является способом решения вашей проблемы, ответ Энди содержит твердые и подробные советы о том, как на самом деле структурировать ваши компоненты.


Помните, что поток данных в React - это однонаправленный. Если вы хотите обмениваться данными с вашим приложением, компонент поиска не должен быть компонентом, который извлекает данные. Это следует оставить родительскому компоненту (возможно, приложению). Этот компонент должен иметь функцию, которая обрабатывает запрос на выборку, и затем вы можете передать ссылка этой функции в компонент поиска для вызова при нажатии кнопки. Затем, как только эти данные загружены, родительский компонент (приложение) может передать все соответствующие данные дочерним компонентам.

Вот быстрый макет, основанный на вашем существующем коде:

class Search extends {

  constructor(props) {
    super(props);
    this.state = { url: '' };
    this.handleKey = this.handleKey.bind(this);
  }

  handleKey(e) {
    const url = e.target.value;
    this.setState({ url });
  }

  render() {
    const { url } = this.state;

    // grab the function passed down from App
    const { fetchData } = this.props;
    return (
      <input onKeyUp = {this.handleKey} value = {url} />

      // Call that function with the url when the button is clicked
      <button onClick = {() => fetchData(url)}>Click</button>
    )
  }
}


class App extends Component {

  constructor(props) {
    super(props);
    this.state = { data: [] };
    this.fetchData = this.fetchData.bind(this);
  }

  // App contains the fetch method
  fetchData(url) {
    fetch(url)
      .then(res => res.json())

      // Update the App state with the new data
      .then(data => this.setState({ data });
  }

  render() {
    const { data } = this.state;

    // Sanity check - if the state is still empty of data, present
    // a loading icon or something
    if (!data.length) return <Spinner />

    // otherwise return the rest of the app components
    // passing in the fetch method as a prop for the search component
    return (
      <OtherComponent data = {data} />
      <Search fetchData = {this.fetchData} />
    )
  }
}