单击按钮后页面未重新呈现

时间:2019-02-13 15:06:23

标签: reactjs gatsby

我有一个React类组件,该组件使用react-sonsonry制作产品展示柜。现在,我想添加过滤功能,将过滤器选项显示为按钮,并在每次单击时,应过滤页面元素,并重新显示砖石结构。 过滤器功能工作正常,但我无法重新砌筑砌体。

import React from 'react'
import PropTypes from 'prop-types'
import Masonry from 'react-masonry-component'
import Product from 'components/Product'


const masonryOptions = {
    transitionDuration: 0
};

class Gallery extends React.Component {
    constructor (props){
        super(props);
        this.state ={
            filter:props.filter,
            elements:props.elements,
            type:props.type,
        }
         this.handleFilterClick=this.handleFilterClick.bind(this)
    }


    handleFilterClick(filter){
        console.log(filter)

        this.setState({filter:filter})
        console.log(this.state.filter)
    }

    filterProducts (elements,filter){
        const filteredArray=elements.filter(function(el){
            for (let i in el.tags) { 
                if (el.tags[i].slug===filter){

                    return true;

                }

            } 
            return false
        })
        return filteredArray;
    }

    renderGallery(){
        const type=this.state.type
        const elements=this.state.elements
        var filter=this.state.filter
        const filteredElements = elements
        if (filter !=="*"){
            const filteredElements = this.filterProducts(elements,filter)
        }

        const childElements = filteredElements.map(function(element,key){

           if (element.mainPhoto!=null && element.isDogFood==type){
           return (

               <Product key={key} element={element}/>

            );} else{
                return null;
            }
        });
         return (



                <Masonry
                    className={'my-gallery-class'} // default ''
                    options={masonryOptions} // default {}
                    disableImagesLoaded={false} // default false
                    updateOnEachImageLoad={false} // default false and works only if disableImagesLoaded is false

                >
                 <div className="col-md-12">

                    <ul className="filter text-center text-inline">
                      <li>
                        <button data-filter="*" className="selected">Tüm Ürünler</button>
                      </li>
                      <li>
                        <button filter="nograin">Tahılsız</button>
                      </li>
                      <li>
                        <button filter="seafood">Deniz Mahsülleri</button>
                      </li>
                      <li>
                        <button filter="poultry">Beyaz Et</button>
                      </li>
                      <li>
                        <button filter="redmeat">Kırmızı Et</button>
                      </li>
                      <li>
                        <button filter="pate" onClick={() =>{this.handleFilterClick("pate")}}>Püre</button>
                      </li>
                    </ul>
                  </div>
                    {childElements}
                </Masonry>


        );

    }

    render() {
       return (
       this.renderGallery()
       )
    }

}

Gallery.propTypes={

    type: PropTypes.bool
}
export default Gallery


1 个答案:

答案 0 :(得分:0)

使用getDerivedStateFromProps代替constructor中的道具

import React from 'react'
import PropTypes from 'prop-types'
import Masonry from 'react-masonry-component'
import Product from 'components/Product'


const masonryOptions = {
    transitionDuration: 0
};

class Gallery extends React.Component {
  constructor (props){
    super(props);
    this.state = {
      // Don't assign direct value in constructor as constructor function 
      // calls only at initialization
      filter:props.filter,
      elements:props.elements,
      type:props.type,
    }
    this.handleFilterClick=this.handleFilterClick.bind(this)
  }

  getDerivedStateFromProps (props, prevState) {
    if(//Put a valid condition) {
      return {
        filter: props.filter,
        elements: props.elements,
        type: props.type
      }
    }
    return {}
  }

  handleFilterClick(filter){
    console.log(filter)
    this.setState({filter:filter})
    console.log(this.state.filter)
  }

  filterProducts (elements,filter){
    const filteredArray=elements.filter(function(el){
      for (let i in el.tags) { 
          if (el.tags[i].slug===filter){
            return true;
          }
      } 
      return false
    })
    return filteredArray;
  }

  renderGallery(){
    const type=this.state.type
    const elements=this.state.elements
    var filter=this.state.filter
    const filteredElements = elements
    if (filter !=="*"){
        const filteredElements = this.filterProducts(elements,filter)
    }

    const childElements = filteredElements.map(function(element,key){

     if (element.mainPhoto!=null && element.isDogFood==type){
     return (
         <Product key={key} element={element}/>
      );} else {
        return null;
      }
    });
    return (
      <Masonry
        className={'my-gallery-class'} // default ''
        options={masonryOptions} // default {}
        disableImagesLoaded={false} // default false
        updateOnEachImageLoad={false} // default false and works only if disableImagesLoaded is false
      >
        <div className="col-md-12">
          <ul className="filter text-center text-inline">
            <li>
              <button data-filter="*" className="selected">Tüm Ürünler</button>
            </li>
            <li>
              <button filter="nograin">Tahılsız</button>
            </li>
            <li>
              <button filter="seafood">Deniz Mahsülleri</button>
            </li>
            <li>
              <button filter="poultry">Beyaz Et</button>
            </li>
            <li>
              <button filter="redmeat">Kırmızı Et</button>
            </li>
            <li>
              <button filter="pate" onClick={() =>{this.handleFilterClick("pate")}}>Püre</button>
            </li>
          </ul>
        </div>
        {childElements}
      </Masonry>
    );
  }

  render() {
   return (
     this.renderGallery()
   )
  }
}

Gallery.propTypes = {
  type: PropTypes.bool
}

export default Gallery