React Hook проблема useEffect с setState - PullRequest
0 голосов
/ 24 января 2020

Я использую useState, который имеет 2 массива imageList и videoList, а затем в ловушке useEffect, я использую forEach для данных, тогда, если type это image, то pu sh для перехода к изображению. Но, наконец, я не получаю список изображений или список видео массива.

const [list, setDataType] = useState({imageList:[], videoList:[] });
  useEffect (()=>{
    //data is list of array
      dataList.forEach(item =>{

       if(!item.images)  {
         setDataType({...list, imageList:item})
       } 
       else if (item.images[0].type === "video/mp4")
       {
        setDataType({...list, videoList :item})
       }
       else if((item.images[0].type === "images/gpeg")
       {
          setDataType({...list, imageList:item})
       }
      })
  },);

Здесь проверка типов работает правильно, но, наконец, я получаю только последние данные выборки, которые могут быть видеолистом или списком изображений. В конце я должен получить список всего списка изображений, тип которого - изображение, и тот же список видео, тип которого - видео

Ответы [ 4 ]

1 голос
/ 24 января 2020

Это неправильный способ вызова setState в al oop. Ниже приводится попытка решения с использованием фильтра метода массива для функционального построения списка.

const [list, setDataType] = useState({ imageList: [], videoList: [] });
useEffect(() => {
    let videos = dataList.filter(item => item.images[0].type === "video/mp4")
    let images = dataList.filter(item => item.images[0].type === "images/gpeg")
    setDataType({imageList: images, videoList: videos})
}, []);


0 голосов
/ 24 января 2020

Не используйте перехватчики useEffect & useState для преобразования данных, которое не является частью асинхронного потока.

Этот случай лучше обрабатывается с помощью useMemo. Когда datalist изменится, useMemo произведет list, и если оно не изменится, будет использовано записанное значение. Кроме того, это не приведет к бесконечному l oop, потому что не вызовет рендеринга при прослушивании своего собственного состояния.

Чтобы создать list, используйте карту, которая будет содержать mime -типы и их соответствующие типы. Уменьшите массив элементов, и в соответствии с типом, который вы получаете с карты, поместите их в подмассивы images или videos.

/** external code (not in the hook) **/
const types = new Map([['video/mp4', 'video'], ['images/gpeg', 'image']])

const getListType = ({ type }) => types.has(type) ? 
  `${types.get(type)}List` : null

/** hook code **/
const list = useMemo(() => dataList.reduce((r, item) => {
  const list = getListType(item.images[0])

  is(list) r[list].push(item)

  return r;
}, { imageList:[], videoList:[] }), [dataList])
0 голосов
/ 24 января 2020

В идеале вы не хотите постоянно вызывать setState внутри вашего l oop. Создайте состояние и затем установите его.

Здесь вам могут подойти два фильтра.

например.

const [list, setDataType] = useState({imageList:[], videoList:[] });
  useEffect (()=>{
    //data is list of array
    setDataType({
      videoList: dataList.filter(item => item.images[0].type === 'video/mp4'),
      imageList: dataList.filter(item => item.images[0].type === 'images/gpeg')
    });
  },);
0 голосов
/ 24 января 2020

Избегайте установки состояния внутри al oop. На каждом setState React будет повторно визуализировать компонент. Поэтому рекомендуется сначала подготовить свое состояние, а затем обновить его.

const [list, setDataType] = useState({imageList:[], videoList:[] });
  useEffect (() =>{
      let newState = {imageList:[], videoList:[] };
      dataList.forEach(item =>{

            if(!item.images)  {
                newState.imageList.push(item);
            } else if (item.images[0].type === "video/mp4") {
                newState.videoList.push(item);
            } else if((item.images[0].type === "images/gpeg") {
                newState.imageList.push(item);
            }
      });
      setDataType(prevState => {
        return {
            imageList: newState.imageList, 
            videoList: newState.videoList 
        }
     });
},[]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...