0

我正在使用 Zusand 来存储状态,除此之外一切正常。当我单击歌曲按钮时,我希望它从列表中过滤。

目前在新加载它显示 3 首歌曲。单击该按钮时,它应该进行过滤(并且首先会过滤),但是一旦我单击另一个按钮再次进行过滤,则什么也没有发生。

所以如果我选择/点击Song 1Song 2应该只显示这些歌曲。

我认为我为此编写的逻辑是正确的,但我必须在重新渲染时做错了什么。

抱歉,我知道人们喜欢在这里上传示例,但我总是觉得使用 React 文件很难,所以对于这种情况,我使用https://codesandbox.io/s/damp-waterfall-e63mn?file=/src/App。 js

完整代码:

import { useEffect, useState } from 'react'
import create from 'zustand'
import { albums } from './albums'

export default function Home() {
  const {
    getFetchedData,
    setFetchedData,
    getAttrData,
    setAttrData,
    getAlbumData,
    getButtonFilter,
    setButtonFilter,
    setAlbumData,
    testState,
  } = stateFetchData()

  useEffect(() => {
    if (getFetchedData) setAttrData(getFetchedData.feed.entry)
  }, [getFetchedData, setAttrData])

  useEffect(() => {
    setAlbumData(getButtonFilter)
  }, [getButtonFilter, setAlbumData])

  // useEffect(() => {
  //   console.log('testState', testState)
  //   console.log('getAlbumData', getAlbumData)
  // }, [getAlbumData, testState])

  useEffect(() => {
    setFetchedData()
  }, [setFetchedData])

  return (
    <div>
      <div>Filter to Show: {JSON.stringify(getButtonFilter)}</div>

      <div>
        {getAttrData.map((props, idx) => {
          return (
            <FilterButton
              key={idx}
              attr={props}
              getDataProp={getButtonFilter}
              setDataProp={setButtonFilter}
            />
          )
        })}
      </div>

      <div>
        {getAlbumData?.feed?.entry?.map((props, idx) => {
          return (
            <div key={idx}>
              <h1>{props.title.label}</h1>
            </div>
          )
        })}
      </div>
    </div>
  )
}

const FilterButton = ({ attr, getDataProp, setDataProp }) => {
  const [filter, setFilter] = useState(false)

  const filterAlbums = async (e) => {
    const currentTarget = e.currentTarget.innerHTML
    setFilter(!filter)
    if (!filter) setDataProp([...getDataProp, currentTarget])
    else setDataProp(getDataProp.filter((str) => str !== currentTarget))
  }

  return <button onClick={filterAlbums}>{attr.album}</button>
}

const stateFetchData = create((set) => ({
  getFetchedData: albums,
  setFetchedData: async () => {
    set((state) => ({ ...state, getAlbumData: state.getFetchedData }))
  },

  getAttrData: [],
  setAttrData: (data) => {
    const tempArr = []
    for (const iterator of data) {
      tempArr.push({ album: iterator.category.attributes.label, status: false })
    }
    set((state) => ({ ...state, getAttrData: tempArr }))
  },

  getButtonFilter: [],
  setButtonFilter: (data) => set((state) => ({ ...state, getButtonFilter: data })),

  testState: {
    feed: { entry: [] },
  },

  getAlbumData: [],
  setAlbumData: (data) => {
    set((state) => {
      console.log(' ~ file: index.js ~ line 107 ~ state', state)
      const filter = state.getAlbumData.feed?.entry.filter((item) =>
        data.includes(item.category.attributes.label),
      )

      return {
        ...state,
        getAlbumData: {
          ...state.getAlbumData,
          feed: {
            ...state.getAlbumData.feed,
            entry: filter,
          },
        },
      }
    })
  },
}))

样本数据:

export const albums = {
  feed: {
    entry: [
      { title: { label: 'Song 1' }, category: { attributes: { label: 'Song 1' } } },
      { title: { label: 'Song 2' }, category: { attributes: { label: 'Song 2' } } },
      { title: { label: 'Song 3' }, category: { attributes: { label: 'Song 3' } } },
    ],
  },
}
4

0 回答 0