React:如何通过按下按钮来复制子组件?

时间:2018-08-13 06:09:37

标签: reactjs clone

我正在尝试克隆一个代表父图库组件中图像的子组件。 主要思想是通过按下图像内部的按钮来复制图像。

问题是我找不到复制特定图像的通知父组件的方法。 我试图将回调方法作为“道具”发送,但效果不佳

class Gallery extends React.Component {
  static propTypes = {
    tag: PropTypes.string  };

  constructor(props) {
    super(props);
    this.state = {
      images: [],
      galleryWidth: this.getGalleryWidth()
    };

  }

  getGalleryWidth(){
    try {
      return document.body.clientWidth;
    } catch (e) {
      return 1000;
    }
  }

  getImages(tag) {
    const getImagesUrl = `services/rest/?method=flickr.photos.search&api_key=522c1f9009ca3609bcbaf08545f067ad&tags=${tag}&tag_mode=any&per_page=100&format=json&safe_search=1&nojsoncallback=1`;
    const baseUrl = 'https://api.flickr.com/';
    axios({
      url: getImagesUrl,
      baseURL: baseUrl,
      method: 'GET'
    })
      .then(res => res.data)
      .then(res => {
        if (
          res &&
          res.photos &&
          res.photos.photo &&
          res.photos.photo.length > 0
        ) {
          this.setState({images: res.photos.photo});
        }
      });
  }

  componentDidMount() {
    this.getImages(this.props.tag);
    this.setState({
      galleryWidth: document.body.clientWidth
    });
  }

  componentWillReceiveProps(props) {
    this.getImages(props.tag);
  }


  clone(img){
    this.setState({images:[img]});
  }


  render() {
    return (
      <div className="gallery-root">
        {this.state.images.map(dto => {
           return <Image key={'image-' + dto.id} dto={dto} callBack={this.clone.bind(this)} galleryWidth={this.state.galleryWidth} />;
        })}
      </div>
    );
  }
}

这是图像组件:

class Image extends React.Component {
  static propTypes = {
    dto: PropTypes.object,
    galleryWidth: PropTypes.number

  };

  constructor(props) {
    super(props);

    this.calcImageSize = this.calcImageSize.bind(this);
    this.onFilter = this.onFilter.bind(this);
    this.onExpand=this.onExpand.bind(this);
    this.closeLightBox=this.closeLightBox.bind(this);

    this.state = {
      size: 200,
      filterType:'none',
      isExpand:false,
      img:props.dto
    };
  }

  calcImageSize() {
    const {galleryWidth} = this.props;
    const targetSize = 200;
    const imagesPerRow = Math.round(galleryWidth / targetSize);
    const size = (galleryWidth / imagesPerRow);

    this.setState({
      size:size,
      isExpand:false
    });
  }

  componentDidMount() {
    this.calcImageSize();
  }

  componentWillReceiveProps(props) {
    this.getImages(props.tag);
  }

  urlFromDto(dto) {
    return `https://farm${dto.farm}.staticflickr.com/${dto.server}/${dto.id}_${dto.secret}.jpg`;
  }

  onClone(){
    this.props.callBack([this.props.dto]);
  }


  render() {
    return (
    <div className="main-div">
      <div
        className="image-root"
        style={{
          backgroundImage: `url(${this.urlFromDto(this.props.dto)})`,
          width: this.state.size + 'px',
          height: this.state.size + 'px',
          filter : this.state.filterType
        }}
        >
        <div>
          <a onClick={this.onClone.bind(this)}><FontAwesome className="image-icon" name="clone" title="clone"/></a>
        </div>
      </div>
    </div>
    );
  }
}

export default Image;

我认为问题出在传递给父级的数据上?显示的结果是一个没有图像的对象。

非常感谢您的帮助。 谢谢

1 个答案:

答案 0 :(得分:0)

在父组件中

 clone(img){
    this.setState({images:[img]});
  }

可以更新为

 clone(img){
    this.setState(
         (prevState)=>{
                prevState.images.push(img);
                return {images:prevState.images}
         }
    );
  }

然后在子组件中


将onClone函数更新为

  onClone(){
    this.props.callBack(this.props.dto);
  }

可能您弄乱了this.state.images数组