javascript 在react中通过改变值的函数后,无法改变变量的值?

deyfvvtc  于 2023-04-28  发布在  Java
关注(0)|答案(2)|浏览(147)

我试图改变filterName值onclick的过滤器按钮,但同时在showFilter function内,该值正在改变,但当我console.log()它外面的showFilter function然后它没有任何值,它显示变量是空的,就像它是如何进入函数之前,请帮助我😭😭😭
主代码(showFilter function和变量,不改变)只是在Filter.js,但我给所有连接到它的文件偶然,如果你需要他们解决问题,谢谢,请帮助我了.
这是过滤器。js

import React, { useState, useEffect } from 'react'
import { FilterBtn } from './FilterBtn'
import { FilterOpt } from './FilterOpt';
import { Items } from './SortItem';

export const Filter = () => {
  const filterNames = ['Color', 'Price', 'Brand', 'All Filters'];
  const [show, setShow] = useState(false);

  const [position, setPosition] = useState('');

  //main function starts here taht would change the value
  let filterName; // the variable which needs to be changed.
  const showFilter = (text) => { // text is the paramenter i am taking from FilterBtn
    if (show === true) {
      setShow(false);
    } else {
      if (text === 'Color') {      // it should change the value from these conditions but its not changing                               
        setPosition('5%');
        filterName = 'color';
      } else if (text === 'Price') {
        setPosition('11.2%');
        filterName = 'price';
      } else if (text === 'Brand') {
        setPosition('17.4%');
        filterName = 'brand';
      } else if (text === 'All Filters') {
        setPosition('24%');
        filterName = 'All Filters';
      }
    }
  }
  console.log(filterName) // filterName needed to have value but it's empty and shows undefined in console.

  useEffect(() => {
    if (document.getElementById('FilterOpt')) {
      document.getElementById('FilterOpt').style.left = position;
    }
  }, [position])

  let itemData = [];
  Items.map((i) => {
    for (const key in i) {
      if (i.hasOwnProperty(key)) {
        itemData.push(`${key}: ${i[key]}`);
      }
    }
  })
  let itemUniqueData = [...new Set(itemData)]
  return (
    <div className="filter_main">
      <div className="left_filter">
        {filterNames.map((filter, index) => {
          return (
            <React.Fragment key={index}>
              // calling the showFilter function here on this BTN
              <FilterBtn text={filter} showFilter={showFilter} />
            </React.Fragment>)
        })}
        {show && (<div id="FilterOpt">
          {itemUniqueData.map((i, index) => {
            if (filterName === 'color') {
              if (itemUniqueData[index].match(filterName)) {
                return (
                  <FilterOpt text={itemUniqueData[index].slice(itemUniqueData[index].indexOf(':') + 2).toUpperCase()} key={index} />
                )
              }
            } else if (filterName === 'price') {
              if (itemUniqueData[index].match(filterName)) {
                return (
                  <FilterOpt text={itemUniqueData[index].slice(itemUniqueData[index].indexOf(':') + 2).toUpperCase()} key={index} />
                )
              }
            } else if (filterName === 'brand') {
              if (itemUniqueData[index].match(filterName)) {
                return (
                  <FilterOpt text={itemUniqueData[index].slice(itemUniqueData[index].indexOf(':') + 2).toUpperCase()} key={index} />
                )
              }
            }
          })}
        </div>)}
      </div>
      <div className="right_filter">
        <button className="filter_btn">Sort By<i className="fa fa-angle-down"></i></button>
      </div>
    </div>
  )
}

这是FilterOpt。js

import React from 'react'

export const FilterOpt = ({ text }) => {
  return (
    <React.Fragment>
      <button>{text}</button>
    </React.Fragment>
  )
}

这是FilterBtn。js

import React from 'react'

export const FilterBtn = ({ text, showFilter }) => {
  return (
    <button className="filter_btn" onClick={() => { showFilter(text) }}> {text} <i className="fa fa-angle-down"></i></button>
  )
}

这是SortItem。js

export const Items = [
  {
    id: 1,
    image: './images/Items/wireless_earbuds.jpg',
    name: 'Wireless Earbuds, IPX8',
    price: 89,
    info: 'Lorem ipsum dolor sit amet.',
    rating: 4.6,
    review: 78,
    type: 'true wireless',
    color: 'black',
    brand: 'IPX8',
    discount: '20',
    microphonepresent: 'yesyes',
    offers: 'buy more save more',
    compaitaiblewith: 'all',
    category: 'audio & video'
  }, {
    id: 2,
    image: './images/Items/airpods_pink.jpg',
    name: 'AirPods Max',
    price: 559,
    info: 'Lorem ipsum dolor sit amet.',
    rating: 5,
    review: 121,
    type: 'true wireless',
    color: 'pink',
    brand: 'IPX8',
    discount: '',
    microphonepresent: 'yes',
    offers: 'no cost EMI',
    compaitaiblewith: 'laptop mobile desktop',
    category: 'audio & video'
  }, {
    id: 3,
    image: './images/Items/bose.webp',
    name: 'Bose BT Earphones',
    price: 289,
    info: 'Lorem ipsum dolor sit amet.',
    rating: 4.2,
    review: 88,
    type: 'wired & wireless',
    color: 'black',
    brand: 'IPX8',
    discount: '25',
    microphonepresent: 'yes',
    offers: 'speical price',
    compaitaiblewith: '',
    category: 'audio & video'
  }, {
    id: 4,
    image: './images/Items/vivefox.webp',
    name: 'VEVEFOX Headphones',
    price: 39,
    info: 'Lorem ipsum dolor sit amet.',
    rating: 4.3,
    review: 90,
    type: 'wired & wireless',
    color: 'red',
    brand: 'IPX8',
    discount: '',
    microphonepresent: 'yes',
    offers: 'no cost EMI',
    compaitaiblewith: 'audio player',
    category: 'audio & video'
  }, {
    id: 5,
    image: './images/Items/jbl.webp',
    name: 'JBL TUNE 60CB TNC',
    price: 59,
    info: 'Lorem ipsum dolor sit amet.',
    rating: 3.7,
    review: 34,
    type: 'wireless',
    color: 'black',
    brand: 'IPX8',
    discount: '30',
    microphonepresent: 'yes',
    offers: 'buy more save more',
    compaitaiblewith: 'desktop',
    category: 'audio & video'
  }
]
pcww981p

pcww981p1#

问题是filterName变量声明在showFilter函数的作用域之外,并且没有保留在状态中。在React中,要保留变量的状态,需要使用useState钩子。每次当你做一些事情,使组件重新渲染filterName变量再次初始化undefined值。你需要做些那样的事

const [filterName, setFilterName] = useState(''); 
const showFilter = (text) => {
    if (show === true) {
      setShow(false);
    } else {
      if (text === 'Color') {
        setPosition('5%');
        setFilterName('color'); // Updating filterName using setFilterName
      } else if (text === 'Price') {
        setPosition('11.2%');
        setFilterName('price'); // Updating filterName using setFilterName
      } else if (text === 'Brand') {
        setPosition('17.4%');
        setFilterName('brand'); // Updating filterName using setFilterName
      } else if (text === 'All Filters') {
        setPosition('24%');
        setFilterName('All Filters'); // Updating filterName using setFilterName
      }
    }
  }

或者你可以将它存储在ref中:

const filterNameRef = useRef(''); 
const showFilter = (text) => {
    if (show === true) {
      setShow(false);
    } else {
      if (text === 'Color') {
        setPosition('5%');
        filterNameRef.current = 'color';
      } else if (text === 'Price') {
        setPosition('11.2%');
        filterNameRef.current = 'price';
     } else if (text === 'Brand') {
        setPosition('17.4%');
         filterNameRef.current = 'brand';
      } else if (text === 'All Filters') {
        setPosition('24%');
        filterNameRef.current = 'All Filters'; 
      }
    }
  }
lkaoscv7

lkaoscv72#

您需要使用useState声明filterName变量,如下所示

const [ filterName, setFilterName ] = useState('');

而不是使用let关键字声明。现在应该没问题了

相关问题