【问题标题】:Child component is not updating from parent state change子组件未从父状态更改更新
【发布时间】:2019-12-23 17:31:24
【问题描述】:

我正在尝试从父组件状态更新我的子组件的照片。对于所有其他路由,一旦安装应用程序,就已经调用了相应的函数。渲染猫、狗或电脑的组件是 PhotoList.js

但是现在,我希望能够在搜索后输入一个参数(例如 /search/:id)并在我的 Container.js 中运行一个名为 getImages 的函数来搜索来自 Flickr API 的任何类型的图片。

我尝试使用 componentDidMount 并使用其中的 match 参数调用 getImages 函数,但它似乎并没有改变放入其中的数据道具。有人对我如何做到这一点有任何建议吗?

这里是 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 

这里是 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;

这里是 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;

【问题讨论】:

    标签: javascript reactjs components


    【解决方案1】:

    假设您使用的是react-router-dom 4 及更高版本。

    试试

    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
    

    【讨论】:

    • 嘿,它确实有效。我认为将 {...props} 放入组件中可以获得匹配对象,但显然不是。我假设没有必要添加它。
    猜你喜欢
    • 2017-05-05
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    • 2020-05-31
    • 2021-04-06
    • 2017-09-28
    • 2021-03-02
    • 1970-01-01
    相关资源
    最近更新 更多