Javascript 我对react电子商务应用程序中的过滤功能有异议

Javascript 我对react电子商务应用程序中的过滤功能有异议,javascript,reactjs,react-hooks,e-commerce,Javascript,Reactjs,React Hooks,E Commerce,反应过滤器功能正在工作 当我点击过滤选项,如“牛仔”,“衬衫”等,它应该过滤产品,只显示这些项目。我使用了handleTag函数来过滤产品数组,然后更新setfilterProducts,但它不起作用 在我的主文件下方Home.jsx function Home() { const [products, setProducts] = useState([]); const [filterProducts, setFileterProducts] = useState([]);

反应过滤器功能正在工作

当我点击过滤选项,如“牛仔”,“衬衫”等,它应该过滤产品,只显示这些项目。我使用了
handleTag
函数来过滤产品数组,然后更新
setfilterProducts
,但它不起作用

在我的主文件下方
Home.jsx

function Home() {
    const [products, setProducts] = useState([]);
    const [filterProducts, setFileterProducts] = useState([]);
    const [sortValue, setSortValue] = useState('');
    const [tag, setTag] = useState('');
    // const [error, setError] = useState('');

    const loadAllProducts = () => {

    /*var myArray = ['a', 1, 'a', 2, '1'];

    let unique = [...new Set(myArray)];

    console.log(unique); // unique is ['a', 1, 2, '1']*/
    let ar = data.map(item => item.tag);
    let uniqueEle = [...new Set(ar)];
    // console.log(uniqueEle);
    setProducts(data);
    setFileterProducts(data);
}

useEffect(() => {
    loadAllProducts();
    handleSort();
    handleTag();
}, [filterProducts, sortValue, tag])

const handleSort = (value) => {
    setSortValue(value);
    listProducts();
}

function listProducts() {
    
    if(sortValue !== '') {
        // console.log("SORT: "+sortValue)
        products.sort((a, b) => sortValue === 'lowest' ? (parseInt(a.price) > parseInt(b.price) ? 1:-1) : (parseInt(a.price) < parseInt(b.price) ? 1:-1))
    } else {
        // console.log("INSIDE THE ELSE PART");
        products.sort((a, b) => (a.id > b.id ? 1 : -1))
    }
    return {setFileterProducts: products}
}

const handleTag = (value) => {
    // console.log(value);
    setTag(value);
    listTagProduct();
}

function listTagProduct() {
    if(tag !== '') {
        if(tag === 'Denim') {
            console.log(tag);
            let filterAr = tagFilter(tag);
            console.log("FilterArr "+filterAr);
            return {setFileterProducts: filterAr}
        } else if(tag === "T-shirt") {
            let filterAr = tagFilter(tag);
            return {setFileterProducts: filterAr}
        } else if(tag === "shirt") {
            let filterAr = tagFilter(tag);
            return {setFileterProducts: filterAr}
        } else if(tag === "jacket") {
            let filterAr = tagFilter(tag);
            return {setFileterProducts: filterAr}
        }
    }
    return {setFileterProducts: products}
}

// utility function
function tagFilter(tag) {
    let ar = filterProducts.filter(item => item.tag === "Denim");
    // console.log(ar);
    return ar;
}

return (
    <div className =  "container-fluid">
        <h2>All Products: {filterProducts.length}</h2>
        <Filter 
            product = {filterProducts} 
            handleSort = {handleSort} 
            sort = {sortValue}
            handleTag = {handleTag}
            tag = {tag}
        />
        <hr />
        <div className="row custom-card">
                {filterProducts.map((product, idx) => {
                    console.log(product);
                    return(
                        
                   

     <div key = {product.id} className="col-md-3 mb-2">
                                <Card products = {product}/>
                            </div>
                        )
                    })}
            </div>
        </div>
    )
}

    export default Home
function Filter(props) {
    const handleChange = (event) => {
        // console.log(event.target.value);
        return props.handleSort(event.target.value);
    }

const handleTagChange = (event) => {
    // console.log(event.target.value);
    return props.handleTag(event.target.value);
}
let tagNames = ["T-shirt", "shirt", "Denim", "jacket"];
return (
    <div className="container-fluid">
        <div className="row">
            <div className="col-12 col-md-9">
                <p className = " mr-2">Filters:<span className="mr-4"></span>
                    {tagNames.map((item, idx) => (
                        <span key = {idx} >
                            <button 
                                type="button" 
                                class="btn btn-outline-secondary mr-2 custom-filter"
                                value= {item}
                                onClick = {handleTagChange}
                            >{item}</button>
                        </span>
                    ))}
                </p>
                </div>
            <div className="col-12 col-md-3">
            <select className="form-control" value = {props.sort} onChange = {handleChange}>
                {/* {console.log("CHECKING: "+props.sort)} */}
                <option value="">Sort by</option>
                <option value="lowest">lowest to highest</option>
                <option value="highest">highest to lowest</option>
            </select>
            </div>
        </div>
    </div>
)

}

    export default Filter


您的
过滤器.jsx
看起来不错,应该可以正常工作。我只做了一些简单的更改,比如内联移动
onClick
事件处理程序,并为选中的按钮添加了一些样式以区分其状态

直接改变状态 另一方面,您的
Home.jsx
看起来过于复杂,所以我需要清理一下。最大的错误之一是直接对各州进行变异。它会导致非常奇怪的错误。您可能甚至没有注意到您更改了状态,但是
products.sort
会对原始
products
数组进行变异

您应该首先克隆阵列(可以使用或),对克隆进行排序,然后使用此新排序的阵列更新状态

奇怪的返回语句 另一个问题是返回对象,如
{setFileterProducts:products}
,或
{setFileterProducts:filterAr}
。我不确定您想做什么,也许它的意思是
setFileterProducts(filter)

使用效果挂钩 下一个问题是
useffect
hook的使用。每次过滤器标签、按值排序或过滤后的产品发生更改时,您都试图加载所有产品,这是绝对不必要的

您可以使用两个
useffects
;一个用于从API加载数据并设置
products
filteredProducts
状态,另一个用于在每次标记或排序值更改时更新
filteredProducts
。您不需要其他任何东西,因为只要
filteredProducts
数组发生更改,React就会重新呈现组件

再简化一些 我更改了一些变量名,并尝试从
Home.jsx
中删除所有不必要的行;只有状态、两个
useffect
hook和return语句保持不变。过滤和排序由钩子处理,不需要为这些操作使用额外的函数

我还简化了排序函数。如果你想,你只需要减去它们(当减法将价格类型更改为一个数字时,你甚至不需要再使用
parseInt

Home.jsx

function Home() {
    const [products, setProducts] = useState([]);
    const [filterProducts, setFileterProducts] = useState([]);
    const [sortValue, setSortValue] = useState('');
    const [tag, setTag] = useState('');
    // const [error, setError] = useState('');

    const loadAllProducts = () => {

    /*var myArray = ['a', 1, 'a', 2, '1'];

    let unique = [...new Set(myArray)];

    console.log(unique); // unique is ['a', 1, 2, '1']*/
    let ar = data.map(item => item.tag);
    let uniqueEle = [...new Set(ar)];
    // console.log(uniqueEle);
    setProducts(data);
    setFileterProducts(data);
}

useEffect(() => {
    loadAllProducts();
    handleSort();
    handleTag();
}, [filterProducts, sortValue, tag])

const handleSort = (value) => {
    setSortValue(value);
    listProducts();
}

function listProducts() {
    
    if(sortValue !== '') {
        // console.log("SORT: "+sortValue)
        products.sort((a, b) => sortValue === 'lowest' ? (parseInt(a.price) > parseInt(b.price) ? 1:-1) : (parseInt(a.price) < parseInt(b.price) ? 1:-1))
    } else {
        // console.log("INSIDE THE ELSE PART");
        products.sort((a, b) => (a.id > b.id ? 1 : -1))
    }
    return {setFileterProducts: products}
}

const handleTag = (value) => {
    // console.log(value);
    setTag(value);
    listTagProduct();
}

function listTagProduct() {
    if(tag !== '') {
        if(tag === 'Denim') {
            console.log(tag);
            let filterAr = tagFilter(tag);
            console.log("FilterArr "+filterAr);
            return {setFileterProducts: filterAr}
        } else if(tag === "T-shirt") {
            let filterAr = tagFilter(tag);
            return {setFileterProducts: filterAr}
        } else if(tag === "shirt") {
            let filterAr = tagFilter(tag);
            return {setFileterProducts: filterAr}
        } else if(tag === "jacket") {
            let filterAr = tagFilter(tag);
            return {setFileterProducts: filterAr}
        }
    }
    return {setFileterProducts: products}
}

// utility function
function tagFilter(tag) {
    let ar = filterProducts.filter(item => item.tag === "Denim");
    // console.log(ar);
    return ar;
}

return (
    <div className =  "container-fluid">
        <h2>All Products: {filterProducts.length}</h2>
        <Filter 
            product = {filterProducts} 
            handleSort = {handleSort} 
            sort = {sortValue}
            handleTag = {handleTag}
            tag = {tag}
        />
        <hr />
        <div className="row custom-card">
                {filterProducts.map((product, idx) => {
                    console.log(product);
                    return(
                        
                   

     <div key = {product.id} className="col-md-3 mb-2">
                                <Card products = {product}/>
                            </div>
                        )
                    })}
            </div>
        </div>
    )
}

    export default Home
function Filter(props) {
    const handleChange = (event) => {
        // console.log(event.target.value);
        return props.handleSort(event.target.value);
    }

const handleTagChange = (event) => {
    // console.log(event.target.value);
    return props.handleTag(event.target.value);
}
let tagNames = ["T-shirt", "shirt", "Denim", "jacket"];
return (
    <div className="container-fluid">
        <div className="row">
            <div className="col-12 col-md-9">
                <p className = " mr-2">Filters:<span className="mr-4"></span>
                    {tagNames.map((item, idx) => (
                        <span key = {idx} >
                            <button 
                                type="button" 
                                class="btn btn-outline-secondary mr-2 custom-filter"
                                value= {item}
                                onClick = {handleTagChange}
                            >{item}</button>
                        </span>
                    ))}
                </p>
                </div>
            <div className="col-12 col-md-3">
            <select className="form-control" value = {props.sort} onChange = {handleChange}>
                {/* {console.log("CHECKING: "+props.sort)} */}
                <option value="">Sort by</option>
                <option value="lowest">lowest to highest</option>
                <option value="highest">highest to lowest</option>
            </select>
            </div>
        </div>
    </div>
)

}

    export default Filter
import React,{useffect,useState}来自“React”;
从“../../../data.json”导入数据;
从“./Card/Card.jsx”导入卡片;
从“./Filter/Filter.jsx”导入过滤器;
导入“/Home.css”;
函数Home(){
const[products,setProducts]=useState([]);
常量[filteredProducts,setFilteredProducts]=useState([]);
const[sortBy,setSortBy]=useState(“”);
const[selectedTag,setSelectedTag]=useState(“”);
useffect(()=>{
产品(数据);
setFilteredProducts(数据);
}, []);
useffect(()=>{
const filtered=selectedTag
?products.filter((项目)=>item.tag==selectedTag)
:产品;
setFilteredProducts(
肮脏的
?[…已筛选].排序((a,b)=>
sortBy==“最低”?a.价格-b.价格:b.价格-a.价格
)
:[…已筛选]。排序((a,b)=>(a.id>b.id?1:-1))
);
},[selectedTag,sortBy,products]);
返回(
产品:{filteredProducts.length}

{filteredProducts.map((产品)=>( ))} ); } 导出默认主页;
Filter.jsx

从“React”导入React;
导入“/Filter.css”;
函数筛选器({handleSort,handleTagChange,selectedTag,sortBy}){
让标记名=[“T恤”、“衬衫”、“牛仔”、“夹克”];
返回(

过滤器: {tagNames.map((tag,idx)=>( handleTagChange(e.target.value)} 值={tag} > {tag} ))}

handleSort(e.target.value)} 值={sortBy} > 排序 从最低到最高 从高到低 ); } 导出默认过滤器;

谁能帮我一下吗?嘿,拉宾德拉,我试着帮你回答下面的问题。你有机会看看吗?这有意义吗?如果答案有用,请单击向上投票按钮(▲) 如果它回答了您的问题,请单击复选标记(✓) 接受它。这样别人就知道你得到了(足够的)帮助。也看到了吗?