我有一个组件将显示来自后端的产品,还有一个组件将接收要过滤的产品,但是我怀疑通过redux接收我的产品列表。
我应该为我的过滤器组件接收吗? 还是应该返回与我在产品组件中获得的相同的东西? 还是应该创建一个操作来过滤我已经需要的内容?
我的家
return (
<div className="container">
<h1>Shopping</h1>
<hr />
<div className="row">
<div className="col-md-3"><Filters/></div>
<div className="col-md-9"><Products/></div>
</div>
</div>
)
我的组件产品:
import React, { Component } from 'react'
import {connect} from 'react-redux'
import { ProductsFetchData } from '../../store/actions/productsFetch';
import util from '../../util';
class HomeProducts extends Component {
componentDidMount() {
this.props.fetchData('/products');
}
render() {
const productItems = this.props.products.map( product => (
<div className="col-md-4 pt-4 pl-2">
<div className = "thumbnail text-center">
<a href={`#${product.id}`} onClick={(e)=>this.props.handleAddToCard(e,product)}>
<p>
{product.name}
</p>
</a>
</div>
<b>{util.formatCurrency(product.price)}</b>
<button className="btn btn-primary" onClick={(e)=>this.props.handleAddToCard(e,product)}>Add to Cart</button>
</div>
)
)
return (
<div className="container">
<div className="row">
{productItems}
</div>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
products: state.Products,
hasErrored: state.ProductsHasErrored,
isLoading: state.ProductsIsLoading
};
};
const mapDispatchToProps = (dispatch) => {
return {
fetchData: () => dispatch(ProductsFetchData())
};
};
export default connect(mapStateToProps, mapDispatchToProps)(HomeProducts);
我的组件过滤器
import React, { Component } from 'react';
import './style.css'
class FilterHome extends Component {
render() {
return (
<>
<div className="row">
<button className="filterbt btn btn-danger btn-rounded">Filters</button>
<div className=" mt-4 d-flex flex-column">
<p className="textCategory">CATEGORY</p>
<div className="category d-flex flex-column">
<a href="" className="text-decoration-none"><p>Stat Trak</p></a>
<a href="" className="text-decoration-none"><p>Normal</p></a>
</div>
<p className="textCategory">EXTERIOR</p>
<div className="category d-flex flex-column">
<a href="" className="text-decoration-none"><p>Factory New ()</p></a>
<a href="" className="text-decoration-none"><p>Minimal Wear ()</p></a>
<a href="" className="text-decoration-none"><p>Field Tested ()</p></a>
<a href="" className="text-decoration-none"><p>Well Worn ()</p></a>
<a href="" className="text-decoration-none"><p>Battle Scarred ()</p></a>
</div>
</div>
</div>
</>
)
}
}
export default FilterHome;
答案 0 :(得分:1)
1. redux-state :这是所有api响应的注册点(来自后端的所有数据都在此处存储为prestine,当您将mapStateToProps用作任何容器的props )。
2. 本地状态:这仅存在于您的容器及其所有子组件中。
3. 过滤器:
a)来自服务器:
您向服务器发出请求,并获得过滤产品的响应。这个 比较实用。 例如:您有 / products?page = 1 ,并且要按某个类别进行搜索,让我们 由特定公司说。根据您目前的数据(第1页), 可能只有1个,甚至没有与该公司相关的产品,但实际上服务器上有n个相同公司的产品可用。所以这只能假设为 最实用的方法。
b)从本地州过滤:
如果这是您要实现的目标, 1.您只需要一个容器,HomeProducts 2.使ProductItems作为组件。我们将重用此组件以同时渲染两者。
**您将过滤器写为一个独立的容器。但是这些过滤器功能应在主页本身内提供。是不是,我的意思是您是从主页本身进行过滤,而不是从其他页面进行过滤。如果是这样,请将其添加到首页本身
1。主页
import React, { Component } from 'react'
import {connect} from 'react-redux'
import { ProductsFetchData } from '../../store/actions/productsFetch';
import util from '../../util';
import ProductItems from '<<..your relative path>>'
import FilterHome from '<<..your relative path>>'
class HomeProducts extends Component {
constructor(props) {
super(props)
this.state = {
productList: null,
}
}
componentDidMount() {
//this.props.fetchData('/products');
this.props.fetchData('page=1');
}
componentWillReceiveProps(nextProps) {
const { productList } = this.state
const { products } = this.props
// this only handles when local state is empty. add your logic here..
!productList && this.setState(prevState => ({
...prevState,
productList: products,
}))
}
handleFilter = (category) => {
// if it's an api call
const { fetchData } = this.props
fetchData(`page=1&category=${category}`)
//or you simply want to filter this local state(not-recommended)
const { products } = this.props
const productsList = [...products].filter(item => item.category === category)
this.setState(prevState => ({
...prevState,
productsList,
}))
}
render() {
const { productList } = this.state
const { handleFilter } = this
return (
<div className="container">
<FilterHome {...{ handleFilter }} />
<ProductItems {...{ productsList }} />
</div>
)
}
}
const mapStateToProps = (state) => {
return {
products: state.Products,
hasErrored: state.ProductsHasErrored,
isLoading: state.ProductsIsLoading
};
};
//it may not suit depends on your api, but you get the idea..
const mapDispatchToProps = (dispatch) => {
return {
// fetchData: () => dispatch(ProductsFetchData())
fetchData: params => dispatch(ProductsFetchData(`/products?${params}`))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(HomeProducts);
2.ProductItems
import React from 'react'
const ProductItem = ({ product }) => {
return (
<div className="col-md-4 pt-4 pl-2">
<div className = "thumbnail text-center">
<a href={`#${product.id}`} onClick={(e)=>this.props.handleAddToCard(e,product)}>
<p>
{product.name}
</p>
</a>
</div>
<b>{util.formatCurrency(product.price)}</b>
<button className="btn btn-primary" onClick={(e)=>this.props.handleAddToCard(e,product)}>Add to Cart</button>
</div>
)
}
const ProductItems = ({ productList }) => {
return (
<div className="row">
{productList && productList.map(product => <ProductItem key={product.id} {...{ product }} />)}
</div>
)
}
export default ProductItems
3.FilterHome
import React from 'react'
const FilterHome = ({ handleFilter }) => {
return (
<div className="row">
<button className="filterbt btn btn-danger btn-rounded">Filters</button>
<div className=" mt-4 d-flex flex-column">
<p className="textCategory">CATEGORY</p>
<div className="category d-flex flex-column">
<a href="" className="text-decoration-none" onClick={() => handleFilter('stat_trak')}><p>Stat Trak</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('normal')}><p>Normal</p></a>
</div>
<p className="textCategory">EXTERIOR</p>
<div className="category d-flex flex-column">
<a href="" className="text-decoration-none" onClick={() => handleFilter('factory_new')}><p>Factory New ()</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('minimal_wear')}><p>Minimal Wear ()</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('field_tested')}><p>Field Tested ()</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('well_worn')}><p>Well Worn ()</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('battle_scarred')}><p>Battle Scarred ()</p></a>
</div>
</div>
</div>
)
}
export default FilterHome
我大致重写了它,可能包含错误。
答案 1 :(得分:0)
首先将其添加到本地状态,然后调用过滤器组件。
handleFilter = (category) => {
const { Products } = this.state
const products = {...Products}
//or depends on the type, so it wont mutate the real data>> const products = [...Products]
return products.filter(item => item.category === category)
}
这是您的评论所能理解的。是吗?