Как можно манипулировать избыточными данными после отправки? - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть экран поиска, который содержит Input и TopTabs «Песни, исполнители»,

Когда я получаю данные из API после поиска, я делаю две вещи

1 - я устанавливаю состояние для отображения Компонент TopTab «true / false» 2 - отправляет действие для сохранения данных о композициях и исполнителях в хранилище приставок.

, что отлично работает.

Но в компоненте topTab, как я уже говорил раньше, у меня есть вкладки буксировки "песни, исполнители"

Например, в компоненте "Песни" я хочу манипулировать данными, чтобы добиться своего результата, поэтому в componentDidMount я сопоставляю массив песен с избыточным и пу sh новым данные в состояние компонента.

Но это не работает нормально!

В первый раз я получил песни из redux как пустые [], хотя они успешно сохраняются в онлайн-хранилище, когда я получаю данные из API

Так, как я могу обработать этот случай, чтобы не изменять данные?

Поиск. js «Главный экран»

onSearch = async () => {
    const {searchText} = this.state;
    if (searchText.length > 0) {
      this.setState({onBoarding: false}); // to appear the TopTab Component
      try {
        let response = await API.post('/search', {
          name: searchText,
        });
        let {
          data: {data},
        } = response;
        let artists = data.artists.data;
        let songs = data.traks.data;
        this.props.getResult(songs, artists);
      }
      catch (err) {
        console.log(err);
      }
}

render(){

<View style={styles.searchHeader}>
          <Input
            onChangeText={text => this.search(text)}
            value={this.state.searchText}
            onSubmitEditing={this.onSearch}
            returnKeyType="search"
          />
        </View>

        {this.state.onBoarding ? (
            <SearchBoard />
        ) : (
          <SearchTabNavigator /> // TopTabs component
        )}
}

SongsTab

...
    componentDidMount() {
        console.log('props.songs', this.props.songs); // Empty [] 
        let All_tunes = [];
        if (this.props.songs?.length > 0) {
          console.log('mapping...');
          this.props.songs.map(track =>
            All_tunes.push({
              id: track.id,
              name: track.name,
              url: URL + track.sounds,
              img: URL + track.avatar,
            }),
          );
          this.setState({All_tunes});
        }
      }
...
    const mapStateToProps = state => {
      return {
        songs: state.searchResult.songs,
      };
    };

Редактирование

Я исправляю проблему с помощью componentDidUpdate() жизненный цикл

Если у вас есть другие способы, скажите мне, пожалуйста!

SongsTab

 manipulateSongs = arr => {
    let All_tunes = [];
    arr.map(track =>
      All_tunes.push({
        id: track.id,
        name: track.name,
        url: URL + track.sounds,
        img: URL + track.avatar,
      }),
    );
    this.setState({All_tunes});
  };

  componentDidMount() {
    if (this.props.songs?.length > 0) {
      this.manipulateSongs(this.props.songs);
      console.log('mapping...');
    }
  }

  componentDidUpdate(prevProps) {
    if (prevProps.songs !== this.props.songs) {
      this.manipulateSongs(this.props.songs);
    }
  }

1 Ответ

0 голосов
/ 01 апреля 2020

Проблема, на которую вы ссылаетесь, связана с тем, как асинхронный код обрабатывается в JavaScript (и, в свою очередь, реагирует на избыточность). Когда ваш компонент изначально монтируется, ваше хранилище резервов передает свое начальное состояние вашему SongsTab.js компоненту. Кажется, это пустой массив.

Любой вызов API является асинхронным действием и не будет обновлять хранилище избыточных данных до тех пор, пока обещание не будет разрешено / отклонено и данные не будут успешно извлечены. Любой HTTP-запрос выполняется намного дольше, чем рисование элементов в DOM. Таким образом, ваш компонент загружается с данными по умолчанию, а затем обновляется ответом от вашего вызова API через несколько миллисекунд.

То, как вы обрабатывали его с помощью компонентов на основе классов, прекрасно. Вероятно, вы можете добавить некоторые оптимизации, но они должны работать как положено. Вы можете даже выбрать визуализацию компонента Spinner при получении данных из API.

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

  const Songs = ({ fetchSongs, songs, ...props }) => {
    React.useEffect(() => {
      // dispatch any redux actions upon mounting
      // handle any component did update logic here as well

    }, [songs])

    // ...the rest of your component
  }

Вот документы для ловушки useEffect.

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