Hi I've been trying out a bit of react and electron and I'm just trying to make a media playlist type of application but I am having a bit of trouble with Redux
So I have setup the actions and they do kind of work but for some reason on the first initial load of a component the array.map that I am using to display all the results in a list won't actually render.
I have got the console out putting the results and when the component renders the first pass of the render fucntion the initial state is null then on the second pass the console logs the correct output but the array.map is still not outputting anything.
Then when I save a file in my editor (hot reload is on) I will then get an item to render on from the array.map
I can't work out if I have made astupid mistake somewhere or if I am just completly doing the wrong thing. So I'm hoping maybe someone might be able to shed some light on the situation.
Here is my component file with this array.map function that isn't working
interface Props {
songs?: any;
receiveMedia?: Function;
}
interface SongState {}
export default class Songs extends React.Component<Props, SongState> {
private initLoad = 0;
constructor(props: Props) {
super(props);
this.state = {};
this.getThumbnailRender = this.getThumbnailRender.bind(this);
}
componentDidMount() {
this.props.receiveMedia && this.props.receiveMedia();
}
getThumbnailRender() {
console.log(this.props.songs);
if (this.props.songs.Media.songs !== null) {
return this.props.songs.Media.songs.map((media: any) => {
if (media.extension !== "mp4") {
return (
<li
className={css.thumbNail}
id={media.id}
key={`${"media_thumb_"}${media.id}`}
>
<img src={mp3} />
<span className={css.floatingText}>{media.fileName}</span>
</li>
);
} else {
return (
<li
className={css.thumbNail}
id={media.id}
key={`${"media_thumb_"}${media.id}`}
>
<img src={media.filePath} />
<span className={css.floatingText}>{media.fileName}</span>
</li>
);
}
});
}
return <div>You haven't added any songs</div>;
}
render() {
return (
<div className={css.container}>
<h1>Songs</h1>
<div className={css.songHolder}>
<ul>{this.getThumbnailRender()}</ul>
</div>
</div>
);
}
}
I'm pretty sure that the Action and the reducer files are fine as they work later on but I will include them just incase I have made a stupid mistake
ACTIONS.ts
import { Songs } from "../../Models";
var fs = require("fs");
export enum ActionTypes {
MEDIA_RECEIVED = "[Media] MEDIA_RECEIVED"
}
export interface MediaReceived {
type: ActionTypes.MEDIA_RECEIVED;
payload: {
globals: Songs;
};
}
export function mediaReceived(json: any): MediaReceived {
return {
type: ActionTypes.MEDIA_RECEIVED,
payload: {
globals: json
}
};
}
function loadInCurrentSongList() {
var obj: Songs = {
//@ts-ignore
songs: []
};
fs.readFile("saveFile.json", "utf-8", (err: any, data: any) => {
if (err) {
alert("An error ocurred reading the file :" + err.message);
return;
}
const newData = JSON.parse(data);
if (newData.songs.length > 0) {
newData.songs.map((song: any) => {
obj.songs.push(song);
});
}
});
return obj;
}
export function receiveMedia() {
return (dispatch: Function) => {
dispatch(mediaReceived(loadInCurrentSongList()));
};
}
export type Action = MediaReceived;
REDUCER.ts
import { Songs } from "../../Models";
import { Action, ActionTypes } from "./Actions";
export interface State {
songs: Songs | null;
}
export const initialState: State = {
songs: null
};
export function reducer(state: State = initialState, action: Action) {
if (action.type === ActionTypes.MEDIA_RECEIVED) {
return Object.assign({}, state, action.payload.globals);
} else {
return state;
}
}
Thank you very much :)

