Обновленное состояние, не отображаемое в дочернем компоненте

#reactjs

#reactjs

Вопрос:

Я пытаюсь извлечь изображение из API НАСА, чтобы получить их астрономическую картину дня. Когда я обновляю состояние в своем вызове API и консоли.зарегистрируйте this.state.picture, я вижу, что picture было установлено для объекта данных. Но когда я пытаюсь зарегистрировать изображение в режиме рендеринга, он регистрирует пустой массив. Я использовал аналогичный подход в предыдущих назначениях и никогда не сталкивался с этой проблемой, поэтому я действительно не могу понять, что я делаю не так. Я новичок в React, поэтому извините, если ответ действительно очевиден.

Родительский компонент:

 class App extends Component {
  state = {
    picture: [],
    asteroids: [],
  }

  render() {
    return (
      <div className="App">
        <Route exact path="/" component={Homepage}/>

        <Route path="/apod" render={() => 
          <APOD picture={this.state.picture}/>}/>

        <Route path="/asteroids" render={() =>
          <Asteroids asteroids={this.state.asteroids} />} />
      </div>
    );
  }
}

export default App;
  

Дочерний компонент:

 class Apod extends React.Component{
  getApodPicture = e => {
    e.preventDefault();

    let url = `https://api.nasa.gov/planetary/apod?api_key=v1sEi9chxFYzrf1uXei0J1GvXaemhnQXiDjEcnK2`;
    fetch(url)
      .then(res => {
        if (!res.ok){
          throw new Error (res.status)
        }
        return res.json();
      })
      .then(data => {
        this.setState({picture: data})
        console.log(this.state.picture) // logs the data object from NASA
      })
      .catch(err => console.log(err))
  }

  render(){
    console.log(this.props.picture) // logs []
    // console.log(this.state.picture) // returns "Cannot read property 'picture' of null"
  return(
    <div>
      <h1>Astronomy picture of the day!</h1>
      <Link to="/">Back to homepage</Link>

      <section>
        <button onClick={e => this.getApodPicture(e)}>Click to see picture</button>
      </section>
    </div>
  )
  } 
}

export default Apod;
  

Ответ №1:

This.setState установит состояние компонента, а не родительского компонента.

для получения желаемого результата вам понадобится обработчик изменений.

что-то вроде

 
class App extends Component {
  state = {
    picture: '',
    asteroids: [],
  }

  pictureChangeHandler = value => {
    this.setState(value);
  }

  render() {
    return (
      <div className="App">
        <Route exact path="/" component={Homepage}/>

        <Route path="/apod" render={() => 
          <APOD pictureChangeHandler={this.pictureChangeHandler} 
 picture={this.state.picture}/>}/>

        <Route path="/asteroids" render={() =>
          <Asteroids asteroids={this.state.asteroids} />} />
      </div>
    );
  }
}

export default App;

class Apod extends React.Component{
  getApodPicture = e => {
    e.preventDefault();

    let url = `https://api.nasa.gov/planetary/apod?api_key=v1sEi9chxFYzrf1uXei0J1GvXaemhnQXiDjEcnK2`;
    fetch(url)
      .then(res => {
        if (!res.ok){
          throw new Error (res.status)
        }
        return res.json();
      })
      .then(data => {
        this.props.pictureChangeHandler(data)

      })
      .catch(err => console.log(err))
  }

  render(){
    console.log(this.props.picture) // logs []
    // console.log(this.state.picture) // returns "Cannot read property 'picture' of null"
  return(
    <div>
      <h1>Astronomy picture of the day!</h1>
      <Link to="/">Back to homepage</Link>

      <section>
        <button onClick={e => this.getApodPicture(e)}>Click to see picture</button>
      </section>
    </div>
  )
  } 
}