UseReduce Hook отправка дважды - ReactJS - PullRequest
0 голосов
/ 09 мая 2020

Я разрабатываю небольшое приложение с целью изучения перехватчиков реакции. Приложение состоит из написания имени исполнителя в разделе. В следующем разделе аналогичная форма для заполнения альбомов каждого исполнителя.

У меня есть отдельные компоненты, а также контекст, статус и редуктор. У меня есть отдельный контекст для каждого исполнителя, альбомов и песен. Когда я нажимаю кнопку исполнителя, я хочу отфильтровать альбомы, чтобы отображались только их альбомы. Но используйте диспетчер редуктора дважды, и в журнале консоли он сообщает мне, что оба исходят из файла редуктора.

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

Еще одна интересная вещь: когда я меняю выбранного исполнителя, он удаляет альбомы состояния, в которых у меня есть все альбомы. Он не фильтрует их, а удаляет их.

Репозиторий GitHub

Это форма, в которой я нажимаю, чтобы вызвать идентификатор каждого исполнителя, и отправил текущий выбранный исполнитель для контекста исполнителя и контекста альбома

import React, { useContext } from "react";

import AlbumContext from "../../context/Album/AlbumContext";
import ArtistContext from "../../context/Artist/ArtistContext";

const Artist = ({ item }) => {
  const albumContext = useContext(AlbumContext);
  const { getArtist } = albumContext;

  const artistContext = useContext(ArtistContext);
  const { artist, getselectedArtist } = artistContext;

  const handleSelect = (artist_id) => {
    getArtist(artist_id);
    getselectedArtist(artist_id);
  };
  return (
    <>
      <div
        style={{ border: "1px solid black", margin: "10px", padding: "5px" }}
      >
        <p>{item.name}</p>
        <button type="button">Edit</button>
        <button type="button">Delete</button>
        <button type="button" onClick={() => handleSelect(item.id)}>
          Select
        </button>
      </div>
    </>
  );
};

export default Artist;

Второй - ALBUMSTATE, где я вызываю функцию getArtist для отправки и получения всех альбомов этого выбранного исполнителя

import React, { useReducer } from "react";

import AlbumContext from "./AlbumContext";
import AlbumReducer from "./AlbumReducer";
import { GET_ARTIST, ADD_ALBUM, VALIDATE_FORM } from "../../types";

const AlbumState = (props) => {
  const initialState = {
    albums: [],
    errorform: false,
    selectedartist: "",
  };

  const [state, dispatch] = useReducer(AlbumReducer, initialState);

  //-----METHODS-----//
  const addAlbum = (album) => {
    dispatch({
      type: ADD_ALBUM,
      payload: album,
    });
  };

  const setError = (error) => {
    dispatch({
      type: VALIDATE_FORM,
      payload: error,
    });
  };

  const getArtist = (id) => {
    dispatch({
      type: GET_ARTIST,
      payload: id,
    });
  };

  return (
    <AlbumContext.Provider
      value={{
        selectedartist: state.selectedartist,
        albums: state.albums,
        errorform: state.errorform,
        addAlbum,
        setError,
        getArtist,
      }}
    >
      {props.children}
    </AlbumContext.Provider>
  );
};

export default AlbumState;

Это ALBUMREDUCER

import { GET_ARTIST, ADD_ALBUM, VALIDATE_FORM } from "../../types";

export default (state, action) => {
  switch (action.type) {
    case ADD_ALBUM:
      return {
        ...state,
        albums: [action.payload, ...state.albums],
      };
    case VALIDATE_FORM:
      return {
        ...state,
        errorform: action.payload,
      };
    case GET_ARTIST:
      console.log(action.payload);
      return {
        ...state,
        selectedartist: action.payload,
        albums: state.albums.filter(
          (album) => album.artist_creator === action.payload
        ),
      };

      return {
        ...state,
        selectedartist: action.payload,
      };

    default:
      return state;
  }
};

1 Ответ

0 голосов
/ 09 мая 2020

Здесь необходимо учитывать две вещи.

  • Вы используете React.strictMode, в котором во время разработки React намеренно дважды вызывает метод отправки. Согласно реакционным документам

Строгий режим не может автоматически обнаруживать побочные эффекты для вас, но он может помочь вам обнаружить их, сделав их более детерминированными c. Это делается путем намеренного двойного вызова следующих функций:

  • Конструктор компонента класса, методы рендеринга и shouldComponentUpdate
  • Состояние компонента класса c Метод getDerivedStateFromProps
  • Тела функциональных компонентов
  • Функции средства обновления состояния (первый аргумент setState)
  • Функции, переданные в useState, useMemo или useReducer
  • Во-вторых вы не прикрепляете альбомы с исполнителем, поэтому ваш artist_creator для каждого альбома всегда имеет значение null, и при попытке фильтрации на его основе будет возвращен пустой массив
case GET_ARTIST:
      console.log(action.payload, state.albums, "getArtistalbum");
      return {
        ...state,
        selectedartist: action.payload,
        albums: state.albums.filter(
          album => album.artist_creator === action.payload
        ) // This returns empty array
      };

  • Последнее, что следует отметить, это то, что вы заменяете исходный массив альбомов в redux отфильтрованным, и, следовательно, все данные ваших альбомов будут удалены. Вместо этого сохраните отдельный ключ для отфильтрованных элементов и отфильтруйте его как

    case GET_ARTIST: console.log (action.payload, state.albums, "getArtistalbum"); return {... state, selectedartist: action.payload, selectedAlbums: state.albums.filter (album => album.artist_creator === action.payload) // Другой ключ для выбранных альбомов отфильтрован из всех альбомов};

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...