Reactjs Redux:mapStateToProps not rendering the component on state change

雨燕双飞 提交于 2019-12-12 15:12:31

问题


I have search filter and sort inputs on the same component.I'm using reselect(selector package) where the data array is filtered and sorted. The mapStateToProps is updating the component on each search filter result.but the mapStateToProps is not updating the component after sorting the array.

selectors/index.js

import { createSelector } from 'reselect'

const getListOfCategory = (state) => state.products.product
const getSearchText = (state) => state.products.searchText
const getSortValue = (state) => state.products.sortValue

export const getVisibleCategory = createSelector(
  [ getListOfCategory, getSearchText, getSortValue ],
  (ListOfCategory, searchText, sortValue) =>{
    if((searchText !== undefined) && (searchText !== null) && (searchText !== "")){
      return ListOfCategory.filter((val) => val.modelname.toLowerCase().includes(searchText.toLowerCase())).sort((a, b) => {
      if (sortValue === 'likes') {
        return b.modellikes - a.modellikes;
      }
      if (sortValue === 'views') {
        return b.modelviews - a.modelviews;
      }
      if (sortValue === 'brand') {
        return a.modelname > b.modelname ? 1 : a.modelname < b.modelname ? -1 : 0;
      }
    });
  }
  if(sortValue){
    return ListOfCategory.sort((a, b) => {
    if (sortValue === 'likes') {
      return b.modellikes - a.modellikes;
    }
    if (sortValue === 'views') {
      return b.modelviews - a.modelviews;
    }
    if (sortValue === 'brand') {
      return a.modelname > b.modelname ? 1 : a.modelname < b.modelname ? -1 : 0;
    }
  });

  }
}
)

Here is my react component.

import React from 'react';
import {connect} from 'react-redux';
import {getCategoryInfo,search,sortBy} from '../actions/productActions';
import {getVisibleCategory} from '../selectors';
import {Link} from 'react-router-dom';

 class SmartCategory extends React.Component{
   constructor(props){
     super(props);
     this.state={
       searchFilter:""
     }
     this.searchHandle=this.searchHandle.bind(this);
     this.sortHandle=this.sortHandle.bind(this);
   }

   searchHandle(e){
     this.setState({
      searchFilter:e.target.value
    });
    this.props.search(e.target.value);
   }

   sortHandle(e){
     this.props.sortBy(e.target.value);
   }

   componentDidMount(){
     this.props.getCategoryInfo(this.props.page,this.props.pageId);
   }

   componentWillReceiveProps(nextProps){
      if(nextProps.page !== this.props.page || nextProps.pageId !== this.props.pageId){
          this.props.getCategoryInfo(nextProps.page,nextProps.pageId);
      }
   }

  changeText(){
    if(this.props.categoryTitle != undefined){
      let categoryTitle=this.props.categoryTitle.charAt(0).toUpperCase() + this.props.categoryTitle.slice(1);
      categoryTitle=categoryTitle.split('_').join(' ');
      return categoryTitle;
    }
  }

render(){
  const {error,isLoading}=this.props
    if(error) return <ResourceNotFound error={error}/>;
    if(isLoading) return <div className="spinner"></div>;
    return (
      <div className="container-fluid mb-4 categoryWrapper">
        <div className="row mx-0 pt-4">
          <div className=" col-sm-2 col-md-2 col-lg-2 px-2">
            <div className="input-group mb-3">
              <div className="input-group-prepend">
                <span className="input-group-text" id="basic-addon1"><i className="fa fa-search" aria-hidden="true"></i></span>
              </div>
              <input type="text"
              className="form-control"
              placeholder="Search by brand"
              onChange={this.searchHandle}
              value={this.state.searchFilter}
               />
            </div>
          </div>
          <div className=" col-sm-2 col-md-2 col-lg-2 px-2">
            <div className="form-group">
              <select className="form-control" id="sel1"
              placeholder="-- Sort By -- "
              onChange={this.sortHandle}
              >
                <option disabled>-- Sort By --</option>
                <option value="brand" >Brand</option>
                <option value="likes">Likes</option>
                <option value="views">Views</option>
              </select>
            </div>
          </div>
        </div>
        <div className="row mx-0 py-3">
          {this.props.isLoading ? <div className="spinner"></div> : null}
            {this.props.product && this.props.product.map((product,i)=>
                <div className="col-sm-3 col-md-3 col-lg-3" key={product.id}>
                  <Link to={`/SmartView/${this.props.page}/${product.modelname}`} className="routeDecorator">
                    <div className="border mb-2 p-3 rounded ">

                        <span className="text-grey">
                        <span className="mr-2">
                        <i className="fa fa-thumbs-o-up" aria-hidden="true"> {product.modellikes}</i>
                        </span>
                        <span className="float-right">
                        <i className="fa fa-eye" aria-hidden="true"> {product.modelviews} views</i>
                        </span>
                        </span>
                    </div>
                  </Link>
                </div>
            )}
        </div>
      </div>
    );
  }
}

function mapStateToProps(state){
  const {isLoading,isLoaded,error,categoryTitle,product,searchText,sortValue} = state.products
    return {
        isLoading,
        error,
        product:getVisibleCategory(state) || product,
        categoryTitle
    }
}

export default connect(mapStateToProps,{getCategoryInfo,search,sortBy})(SmartCategory);

回答1:


MapStateToProps does a shallow compare of the values returned each time. A shallow compare will compare references for objects and arrays. When you sort, the array is sorted in place, so the reference doesn't change. See sort. You could prove it by returning a new reference to the array:

 return [...ListOfCategory.sort(a,b) // rest of sort code ]


来源:https://stackoverflow.com/questions/48475537/reactjs-reduxmapstatetoprops-not-rendering-the-component-on-state-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!