reactjs - 来自redux的array.map不会在第一次加载react组件时返回数据
问题描述
嗨,我一直在尝试一些反应和电子,我只是想制作一个媒体播放列表类型的应用程序,但我在使用 Redux 时遇到了一些问题
所以我已经设置了动作并且它们做了一些工作,但是由于某种原因,在组件的第一次初始加载时,我用来在列表中显示所有结果的 array.map 不会实际呈现。
我已经让控制台输出结果,当组件渲染渲染功能的第一遍时,初始状态为空,然后在第二遍时控制台记录正确的输出,但 array.map 仍然没有输出任何东西。
然后,当我在编辑器中保存文件(热重载已打开)时,我将从 array.map 获取要渲染的项目
我无法弄清楚我是否在某个地方犯了愚蠢的错误,或者我只是在做错事。所以我希望也许有人能够对这种情况有所了解。
这是我的组件文件,其中的 array.map 函数不起作用
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>
);
}
}
我很确定 Action 和 reducer 文件在以后工作时很好,但我会包括它们以防我犯了一个愚蠢的错误
行动.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;
减速器.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;
}
}
非常感谢 :)
解决方案
因为fs.readFile
是异步的,并且传递给它的回调会在稍后 fs 操作完成时执行,它是在填充歌曲之前obj
返回的,因此何时调度仍然是空的。您的调试器有点愚弄您,因为它显示了在回调中填充后的更新值。loadInCurrentSongList
mediaReceived
songs
obj
fs.readFile
热重载之所以有效,是因为它强制重新渲染而不破坏状态,此时obj
已在fs.readFile
回调内部发生了变异。
这是使用 Promise 管理异步性质的一种选择,fs.readFile
这样您就可以等待它完成而不是改变obj
从loanInCurrentSongList
. 对打字稿不太熟悉,因此您可能必须更新类型:
function loadInCurrentSongList() {
return new Promise(resolve => {
fs.readFile("saveFile.json", "utf-8", (err: any, data: any) => {
var obj: Songs = {
//@ts-ignore
songs: []
};
if (err) {
alert("An error ocurred reading the file :" + err.message);
resolve(obj);
return;
}
const newData = JSON.parse(data);
if (newData.songs.length > 0) {
newData.songs.map((song: any) => {
obj.songs.push(song);
});
}
resolve(obj);
});
}
export function receiveMedia() {
return (dispatch: Function) => {
loadInCurrentSongList().then(songList => {
dispatch(mediaReceived(songList));
}
};
}
推荐阅读
- reactjs - React Bootstrap 添加到组件中 - 卡片
- snowflake-cloud-data-platform - 需要澄清雪花问题
- android - 扫描条形码时是否可以使用图像处理?
- scheme - 方案附加到列表而不附加?
- python - 在 Python 中将日期转换为人类可读的格式(明天,2 天前)
- r - 在 igraph 中合并或组合顶点
- python-3.x - Chromedriver V93+ 错误消息“Windows 无法访问指定的设备、路径或文件。您可能没有适当的权限来访问该文件
- c# - Dialog 的 ViewModel 和 View 创建新对象而不删除以前的对象
- c++ - 存储必须由多个源文件读取但仅在运行时知道的值的最佳方法是什么
- dask - 如何正确地保留在 dask 数据框中?