Я использую https://github.com/cinder92/react-native-get-music-files для получения музыкальных файлов на устройстве пользователя с моим приложением, я использую избыточное сохранение, чтобы когда музыка загружается один раз на телефон пользователя и пользователь приходит Возвращаясь к приложению, он будет просто проверять наличие новой музыки, отсутствующей в массиве состояний tracks
, ему не придется повторно сканировать всю музыку, он будет просто проверять наличие новой музыки в фоновом режиме, но состояние обычно содержит двойное данные (обычно перезагружает музыку, показывает музыку 1-5, затем музыку 1-10) и не загружает всю музыку на телефон человека, просто останавливается на полпути, когда я использую нормальные состояния, то есть this.setState
вся музыка на телефоне пользователя обычно загружается пожалуйста что я могу делать не так
Это мой код ниже
Магазин - index.js
import { createStore } from "redux";
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import rootReducer from "../reducers/index";
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
const persistConfig = {
key: 'root',
storage,
// stateReconciler: autoMergeLevel2,
timeout: 0,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer)
let persistor = persistStore(store)
return { store, persistor }
}
Actions- index.js
export const addSong = song => ({type:
"ADD_SONG", payload: song
});
export const RESET_ACTION = {
type: "RESET"
}
Редукторы - index.js
import{ADD_SONG,RESET} from "../constants/action-types";
const initialState = {
tracks: []
};
const rootReducer = (state = initialState, action) => {
switch (action.type){
case ADD_SONG:
let index = state.tracks.findIndex(tracks => tracks.id == action.payload.id);
if(index != -1){
return state;
}else{
return {
...state,
tracks: [...state.songs, action.payload]
}
}
case RESET:
return initialState;
default:
return state
}
}
export default rootReducer;
App.js
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
Image,
Dimensions,
StatusBar,
ScrollView,
View,
DeviceEventEmitter,
FlatList,
ActivityIndicator,
AsyncStorage
} from 'react-native';
import Splash from './components/Splash';
import Home from './components/Home';
import MusicFiles from 'react-native-get-music-files';
import Permissions from 'react-native-permissions';
import { PersistGate } from 'redux-persist/integration/react';
//import store from "./store/index";
import index from './store/index';
const {store, persistor} = index();
import {connect, Provider} from 'react-redux';
import {addSong, RESET_ACTION
} from "./actions/index";
const mapStateToProps = state => {
return {
tracks: state.tracks
};
};
const mapDispatchToProps = dispatch => {
return {
addSong: song => dispatch(addSong(song)),
RESET_ACTION
};
};
class reduxApp extends Component{
millisToMinutesAndSeconds(millis) {
var minutes = Math.floor(millis / 60000);
var seconds = ((millis % 60000) / 1000).toFixed(0);
return (seconds == 60 ? (minutes+1) + ":00" : minutes + ":" + (seconds < 10 ? "0" : "") + seconds);
}
componentDidMount() {
this.props.RESET_ACTION;
this.setState({loaded: false});
if(this.props.songs && this.props.songs.length > 0){
this.setState({loaded: true})
}else{
this.musicGetter();
}
}
musicGetter(){
Permissions.request('storage').then(response => {
this.setState({ photoPermission: response })
})
MusicFiles.getAll({
id : true,
blured : false,
artist : true,
duration : true, //default : true
cover : true, //default : true,
title : true,
cover : true,
batchNumber : 1, //get 5 songs per batch
minimumSongDuration : 10000, //in miliseconds,
fields : ['title','artwork','duration','artist','genre','lyrics','albumTitle']
})
}
componentWillMount() {
/* DeviceEventEmitter.addListener(
'onBatchReceived',
(params) => {
this.setState({songs : [
...this.state.songs,
...params.batch
]},this.setState({loaded: true}));
}
);*/
DeviceEventEmitter.addListener(
'onBatchReceived',
(params) => {
console.log(params.batch);
this.props.addSong(params.batch);
this.setState({loaded: true});
},
);
}
async asynccer(){
try {
await AsyncStorage.setItem('@MySuperStore:songs', JSON.stringify(this.state.songs));
} catch (error) {
// Error saving data
}
}
constructor(props) {
super(props);
this.state = {
timePassed: false,
photoPermission: '',
songs: [],
loaded: true,
loading: false
};
}
render() {
if (!this.state.loaded) {
return (
<Splash/>
);
} else {
return (
<View style={styles.linearGradient}>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<Home songs={this.props.tracks}/>
</PersistGate>
</Provider>
</View>
);
}
}
}
function connectWithStore(store, WrappedComponent, ...args) {
var ConnectedWrappedComponent = connect(...args)(WrappedComponent)
return function (props) {
return <ConnectedWrappedComponent {...props} store={store} />
}
}
const App = connectWithStore(store, reduxApp,mapStateToProps, mapDispatchToProps);
export default App;
Home.js
render() {
const lyrics = this.props.songs.map((song, index) =>
<View style={styles.musicBox} key={index}>
<View style={{width: 57, height: 59, borderRadius: 9, marginLeft: 15}}>
<Image resizeMode="contain"
style={{alignSelf: 'center', borderRadius: 9, width: 57, height: 59}}
source={{uri: song[0].cover}}/>
</View>
<View style={styles.TextBox}>
<Text
numberOfLines={1}
style={{fontFamily: 'nexaBold', fontSize: 20, color: 'white', flex: 1}}>
{song[0].title}
</Text>
<View style={{flexDirection: 'row', }}>
<Text
numberOfLines={1}
style={{fontFamily: 'nexaLight', fontSize: 10, color: '#917D7D',
marginRight: 5, }}>
{song[0].author}
</Text>
<View style={{alignSelf:'center',width: 2, height: 2, borderRadius: 1, backgroundColor: '#917D7D',marginRight: 5}}>
</View>
<Text style={{fontFamily: 'nexaLight', fontSize: 10, color: '#917D7D'}}>
{this.millisToMinutesAndSeconds(song.duration)}
</Text></View>
</View>
</View>
);
const music =
<ScrollView overScrollMode={'never'} keyboardShouldPersistTaps='always'>
{lyrics}</ScrollView>;
const shadowOpt = {
color: "#000",
border: 12,
opacity: '0.08',
radius: 12,
x: 0,
y: 1,
};
return (
<View style={{flex: 1}}>
<View style={styles.linearGradient}>
{music}
</View>
</View>
);
}
}