Магазин не обновляется в Redux? - PullRequest
1 голос
/ 26 февраля 2020

В редукторе «Список избранного» * ​​1001 *

У меня есть два вспомогательных элемента «Добавить / Удалить» из массива

. Добавление работает хорошо, но удаление не приводит к обновлению хранилища в фактическое время, потому что в моем пользовательском интерфейсе есть средство проверки, которое проверяет, есть ли этот song_id в массиве или нет, и основано на нем, я обновляю значок сердца, НО он не работает, когда я отправляю действие удаления, Другими словами" Not Re-render компонента "!.

Файл действий

import {ADD_TO_FAVORITE, REMOVE_FROM_FAVORITE} from './types';

export const addToFavoriteFunction = track_id => {
  return {
    type: ADD_TO_FAVORITE,
    payload: track_id,
  };
};

export const removeFromFavoriteFunction = track_id => {
  return {
    type: REMOVE_FROM_FAVORITE,
    payload: track_id,
  };
};

Редуктор

import {ADD_TO_FAVORITE, REMOVE_FROM_FAVORITE} from '../actions/types';

let initialState = [];

const addSongFav = (songs, songId, flag) => {
  if (songs.some(song => song.track_id === songId)) {
    return songs;
  } else {
    let isFav = {track_id: songId, isFavorite: flag};
    return [...songs, isFav];
  }
};

const removeSongFav = (songs, songId) => {
  const newState = songs.filter(song => song.track_id !== songId);
  return newState;
};


const isFavoriteReducer = (state = initialState, action) => {
  const {payload, type} = action;
  switch (type) {
    case ADD_TO_FAVORITE: {
      return addSongFav(state, payload, true);
    }
    case REMOVE_FROM_FAVORITE:
      return removeSongFav(state, payload);
    default:
      return state;
  }
};

export default isFavoriteReducer;

"Musi c Player Component"

 ....
 checkFavorite = () => {
    let {currentTrackIndex, tunes} = this.state;
    console.log(tunes[currentTrackIndex].id);
    let id = tunes[currentTrackIndex].id;
    let songs = this.props.favorite;
    let isFavorite = songs.some(song => song.track_id === id);
    this.setState({isFavorite});
  };

componentDidMount() {
    this.checkFavorite();
  }



  addToFavorite = async () => {
    const {tunes, token, currentTrackIndex} = this.state;
    this.setState({isFavorite: true});
    let id = tunes[currentTrackIndex].id;
    try {
      this.props.addToFavoriteAction(id);
      let AuthStr = `Bearer ${token}`;
      const headers = {
        'Content-Type': 'application/json',
        Authorization: AuthStr,
      };
      //  here i send a hit the endoint
    } catch (err) {
      this.setState({isFavorite: false});
      console.log(err);
    }
  };


deleteFromFavorite = async () => {
    const {tunes, token, isFavorite, currentTrackIndex} = this.state;
    let id = tunes[currentTrackIndex].id;
    this.props.removerFromFavoriteAction(id);
    try {
      let AuthStr = `Bearer ${token}`;
      const headers = {
        'Content-Type': 'application/json',
        Authorization: AuthStr,
      };
      // here i send a hit the endoint
    } catch (err) {
      console.log(err);
    }
  };



<Button onPress={() => this.state.isFavorite
                  ? this.deleteFromFavorite()
                  : this.addToFavorite()} >
  <Icon name={this.state.isFavorite ? 'favorite' : 'favorite-border'} />
</Button>

....

const mapDispatchToProps = dispatch => {
  return {
    incrementCount: count => {
      dispatch(incrementCount(count));
    },

    addToFavoriteAction: track_id => {
      dispatch(addToFavoriteFunction(track_id));
    },

    removerFromFavoriteAction: track_id => {
      dispatch(removeFromFavoriteFunction(track_id));
    },
  };
};

mapStateToProps = state => {
  return {
    favorite: state.favorite,
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(MusicPlayer);

1 Ответ

5 голосов
/ 27 февраля 2020

Спасибо за живую демонстрацию, она очень помогла увидеть всю картину. Проблема в том, что ваш взгляд вообще не использует значения в вашем хранилище Redux . Редуктор в порядке, и все работает за кадром, но посмотрите ...

const mapStateToProps = state => {
  return {
    favorite: state,
  };
};

Это ваш метод mapStateToProps, а favorite содержит массив любимых треков, который успешно обновляется всякий раз, когда вы отправляете действие. Причина, по которой ваше представление не обновляется соответствующим образом, заключается в том, что вы нигде не используете этот массив.

<Icon
  style={{color:"#00f"}}
  type="MaterialIcons"
  name={this.state.isFavorite ? 'favorite' : 'favorite-border'}
/>

В этом фрагменте кода вы проверяете значение isFavorite свойство внутри внутреннего состояния вашего компонента . Причина, по которой это работает, когда вы добавляете избранное, в том, что вы звоните setState в начале addToFavorite. Напротив, deleteFromFavorite отсутствует этот вызов setState, поэтому ваша иконка не меняется.

Если вы хотите использовать то, что есть в магазине Redux, чтобы определить, какую иконку показывать, Вы должны изменить свой код, чтобы он использовал this.props.favorite, то есть свойство, которое фактически ссылается на магазин и изменяется в соответствии с вашими действиями.

const isCurrentTrackFavorite = () => {
  const { tunes, currentTrackIndex } = this.state;
  const currentTrackId = tunes[currentTrackIndex].track_id;

  // Check array in the Redux store to see if the track has been added to favorites
  return this.props.favorite.findIndex(track => track.track_id === currentTrackId) != -1;
};

render() {
  <Icon
    style={{color:"#00f"}}
    type="MaterialIcons"
    name={isCurrentTrackFavorite() ? 'favorite' : 'favorite-border'}
  />
}

После внесения этого изменения ваш компонент будет действительно прослушивать содержимое магазина и должен обновлять представление всякий раз, когда изменяется массив избранных.

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