简体   繁体   中英

Child component is not updating from parent state change

I'm trying to update my child component's photos from the parent components state. For all the other routes, the appropriate function was already invoked once the app was mounted. The component that renders cats, dogs, or computers is PhotoList.js

But now, I want to be able to enter a parameter after search (ex. /search/:id) and run a function called getImages in my Container.js to search for any type of picture from the Flickr API.

I tried using componentDidMount and invoking the getImages function with the match parameter inside of it but it doesn't seem to change the data props that's put into it. Does anyone have any suggestions as to how I can make this?

Here is Container.js

import React, {Component} from 'react';
import Photo from './Photo';

class Container extends Component {

  componentDidMount() {
    this.props.getImages(this.props.match.id)
  }

  render() {
    return (
      <div className="photo-container">
        <h2>Results</h2>
        <ul>
          {this.props.data.map((photo,index)=> 
            <Photo 
              farm={photo.farm}
              server={photo.server} 
              id={photo.id}
              secret={photo.secret}
              key={index}
            />
          )}
        </ul>
      </div>
    );
  }
} 


export default Container 

Here is PhotoList.js

import React, {Component} from 'react';
import Photo from './Photo';
import NoResults from './NoResults';

class PhotoList extends Component {

  render() {
    return (
      <div className="photo-container">
        <h2>Results</h2>
        <ul>
          {this.props.data.map((photo,index)=> 
            <Photo 
              farm={photo.farm}
              server={photo.server} 
              id={photo.id}
              secret={photo.secret}
              key={index}
            />
          )}
        </ul>
      </div>
    );
  }
}   


export default PhotoList;

Here is App.js

import React, {Component} from 'react';
import {
  BrowserRouter,
  Route,
  Switch,
  Redirect
} from 'react-router-dom';
import Search from './Search';
import Nav from './Nav';
import '../index.css';
import axios from 'axios';
import apiKey from './Config';
import NotFound from './NotFound';
import PhotoList from './PhotoList';
import NoResults from './NoResults';
import Container from './Container';


class App extends Component {

  state= {
    cats: [],
    dogs: [],
    computers: [],
    searchResult: [],
    loading: true
  }

  componentDidMount() {
    this.getCats()
    this.getDogs()
    this.getComputers()
  }


  getCats=(query='cats')=> {
    axios.get(`https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${apiKey}&tags=${query}&per_page=24&page=1&format=json&nojsoncallback=1`)
      .then(res=> {
        const cats=res.data.photos.photo
        this.setState({cats})
      }).catch((error)=> {
        console.log("There was an error parsing your data", error);
      })
  }

  getDogs=(query='dogs')=> {
    axios.get(`https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${apiKey}&tags=${query}&per_page=24&page=1&format=json&nojsoncallback=1`)
      .then(res=> {
        const dogs=res.data.photos.photo
        this.setState({dogs})
      }).catch((error)=> {
        console.log("There was an error parsing your data", error);
      })
  }

  getComputers=(query='computers')=> {
    axios.get(`https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${apiKey}&tags=${query}&per_page=24&page=1&format=json&nojsoncallback=1`)
      .then(res=> {
        const computers=res.data.photos.photo
        this.setState({computers});
      }).catch((error)=> {
        console.log("There was an error parsing your data", error);
      })
  }

  getImages=(query)=> {
    axios.get(`https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=${apiKey}&tags=${query}&per_page=24&page=1&format=json&nojsoncallback=1`)
      .then (res=> {
        const searchResult=res.data.photos.photo
        this.setState({searchResult});
      }).catch((error)=> {
        console.log("There was an error parsing your data", error);
      })
  }


  render() {
    return (
      <div className="container">
        <Search getImages={this.getImages}/>
        <Nav />
        <Switch>
          <Route exact path="/" render={()=> <Redirect to={'/cats'} />} />
          <Route path='/cats' render={()=> <PhotoList data={this.state.cats}/>} />
          <Route path='/dogs' render={()=> <PhotoList data={this.state.dogs} />} />
          <Route exact path='/computers' render={()=> <PhotoList data={this.state.computers} />} />
          <Route path='/search/:id' render={(props)=> <Container {...props} getImages={this.getImages} data={this.state.searchResult} />} />
          <Route component={NotFound}/>
        </Switch>
      </div>
    )
  }
}

export default App;

Assuming your are using react-router-dom 4 and above.

Try

import React, { Component } from "react";
import { withRouter } from "react-router-dom"; //<-- import this
import Photo from "./Photo";

class Container extends Component {
  componentDidMount() {
    // Your this.props.match.id is likely undefined
    this.props.getImages(this.props.match.params.id); // <-- Change here
  }

...

}

export default withRouter(Container); // <-- Change this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM