GiroteQ
GiroteQ

Reputation: 53

React, useState: The array contained in the object is changed to undefined

I have a home page and a component that is used on the home page. On the home page I have a "filterData" object declared with useState:

const [filterData, setFilterData] = useState({
searchingPhrase: "",
categories: [],
priceRange: {
    minValue: null,
    maxValue: null,
}

})

I add filterData and setFilterData to the prop component. As you can see, in the component I have a function for retrieving the searched name and a list of categories that, when clicked, is to enter / remove from / into filterData.categories.
The value from input seamlessly enters the string into filterData.searchingPhrase.
There is a problem with working on the filterData.categories table, because the final result after clicking on one of the categories is converting the table to undefined.

This is my console.log since clicking one of the categories:

/ * mycoponent.js * / Loading productfilter
/ * mycoponent.js * / imprtnt {searchingPhrase: '', categories: Array (0), priceRange: {…}}
/ * mycoponent.js * / imprtnt {searchingPhrase: '', categories: Array (0), priceRange: {…}}
/ * mycoponent.js * / imprtnt {searchingPhrase: '', categories: Array (0), priceRange: {…}}
/ * mycoponent.js * / imprtnt {searchingPhrase: '', categories: Array (0), priceRange: {…}}
/ * mycoponent.js * / imprtnt {searchingPhrase: '', categories: Array (0), priceRange: {…}}
/ * mainPage.js * / {searchingPhrase: '', categories: Array (1), priceRange: {…}}
/ * myComponent.js * / Loading productfilter
/ * myComponent.js * / imprtnt {searchingPhrase: '', categories: undefined, priceRange: {…}}
/ * myComponent.js * / imprtnt {searchingPhrase: '', categories: undefined, priceRange: {…}}
/ * myComponent.js * / imprtnt {searchingPhrase: '', categories: undefined, priceRange: {…}}
/ * myComponent.js * / imprtnt {searchingPhrase: '', categories: undefined, priceRange: {…}}
/ * myComponent.js * / imprtnt {searchingPhrase: '', categories: undefined, priceRange: {…}}

I would like to note that the category is added to the array, but after the component seems to reload, replacing the array with undefined.

The most important piece of code from the home page:

const instantWebsites = ({ navigation, products, allCategories }) => {
    const [filterData, setFilterData] = useState({
        searchingPhrase: "",
        categories: [],
        priceRange: {
            minValue: null,
            maxValue: null,
        }
    })
  return (
                        <ProductFilter 
                            allCategories={allCategories}
                            state={filterData}
                            setState={setFilterData}
                        />
  )
}

The most important piece of code from the component:

const ProductFilter = ({allCategories, state, setState}) => {
    console.log('Loading productfilter')
    const handleSearchInput = (event) => { 
        const {value} = event.target
        setState({ 
            ...state, 
            searchingPhrase: value
        }) 
    }
    const handleClickCategory = (name) => {
        var label = document.querySelector(`#category-${name} h2`)
        var newArr;
        name = name.toLowerCase()
        const removeCategory = () => {
            wArr = state.categories.splice(state.categories.indexOf(name),1)
            //label.classList.remove(style.categoryLabel__active)
        }
        const addCategory = () => {
            var newArr = state.categories.push(name)
            label.classList.add(style.categoryLabel__active)
        }

        (state.categories.indexOf(name) >= 0) ? removeCategory() : addCategory() ;
        setState({
            ...state,
            categories: newArr
        })
        console.log(state)
    }

    return (
        <>
                <div className={style.filterContainer__content}>
                    <input
                        name="wordSearchInput"
                        value={state.searchingPhrase}
                        onChange={handleSearchInput}
                    />
                </div>
                <div className={style.filterContainer__cat}>

                    {allCategories.map( ({attributes, id}) => {
                        {console.log('imprtnt', state)}
                            if (attributes.products.data.length > 0) return (
                                <div id={"category-"+attributes.name} className={ style.filterContainer__cat__row }
                                    key={id}
                                    onClick={()=> handleClickCategory(attributes.name)}
                                >
                                <h2>{attributes.name}</h2><p>({attributes.products.data.length})</p>
                                </div>
                            )
                    } )}

                </div>
        </>
   )

Upvotes: 0

Views: 415

Answers (1)

imer
imer

Reputation: 63

var newArr = state.categories.push(name);

This part looks like it needs to be replaced with a newArr.push format.

It might be wrong, but I'm going to post a rough code.

Is there a way to test it?

const ProductFilter = ({ allCategories, state, setState }) => {
  console.log("Loading productfilter");

  //   memo hook change allCategories
  const allCate = useMemo(() => allCategories ?? [], [allCategories]);

  const handleSearchInput = useCallback(
    (event) => {
      const { value } = event.target;
      setState({
        ...state,
        searchingPhrase: value,
      });
    },
    [state, setState]
  );

  const handleClickCategory = useCallback(
    (name) => {
      var label = document.querySelector(`#category-${name} h2`);
      var newArr = [];
      name = name.toLowerCase();

      const removeCategory = () => {
        wArr = state.categories.splice(state.categories.indexOf(name), 1);
        //label.classList.remove(style.categoryLabel__active)
      };
      const addCategory = () => {
        newArr.pust(name)
        //  = state.categories.push(name);
        label.classList.add(style.categoryLabel__active);
      };

      state.categories.indexOf(name) >= 0 ? removeCategory() : addCategory();
      setState({
        ...state,
        categories: newArr ?? [],
      });
      console.log(state);
    },
    [state, setState]
  );

  return (
    <>
      <div className={style.filterContainer__content}>
        <input
          name="wordSearchInput"
          value={state.searchingPhrase}
          onChange={handleSearchInput}
        />
      </div>
      <div className={style.filterContainer__cat}>
        {(allCate ??[]).map(({ attributes, id }) => {
          {
            console.log("imprtnt", state);
          }
          if (attributes.products.data.length > 0)
            return (
              <div
                id={"category-" + attributes.name}
                className={style.filterContainer__cat__row}
                key={id}
                onClick={() => handleClickCategory(attributes.name)}
              >
                <h2>{attributes.name}</h2>
                <p>({attributes.products.data.length})</p>
              </div>
            );
        })}
      </div>
    </>
  );
};

export default ProductFilter;

Upvotes: 1

Related Questions