我几个小时以来一直坚持这个问题。我想实现Flux架构。我正在尝试创建ToDo列表。但是,我想先加载一些初始数据。例如在我的todoStore.js中:
import { EventEmitter } from "events";
class ToDoStore extends EventEmitter {
constructor(){
super();
this.bucket_list = [{
id: 123,
name: "Hi",
isCompleted: false
}]
}
getAll(){
return this.bucket_list;
}
}
我这里有一些初始数据,我的todo.js
使用了
import toDoStore from './stores/todoStore'
class BucketApp extends React.Component {
constructor(props) {
super(props);
this.state = {
bucket_list: toDoStore.getAll()
};
}
这很好用,花花公子。我的商店基本上是collection
我的component
从中接收数据。但是,现在我想初始化数据库中的数据。所以我更新了todoStore.js
:
class BucketlistStore extends EventEmitter {
constructor(){
super();
fetch(url)
.then(d => d.json())
.then(d => {
this.bucket_list = d;
});
}
getAll(){
return this.bucket_list;
}
}
但是,getAll()返回undefined
。为什么会这样?我做错了什么?
答案 0 :(得分:1)
由于fetch
是异步操作,您可能过早地调用getAll()
吗?这不是一个解决方案,但你可以检查一下这个假设:
class BucketlistStore extends EventEmitter {
constructor(){
super();
this.loading = true;
fetch(url)
.then(d => d.json())
.then(d => {
this.loading = false;
this.bucket_list = d;
});
}
getAll(){
console.log(this.loading);
return this.bucket_list;
}
}
如果这是真的,我建议在BucketApp
为loading
时不要呈现true
。将标志存储起来并在BucketApp
中使用它以防止渲染(显示加载器)。
答案 1 :(得分:1)
它返回undefined
,因为提取数据是异步的,并且在初始化期间this.bucket_list
未定义。试试这个:
class BucketlistStore extends EventEmitter {
constructor(){
super();
this.bucket_list_promise = fetch(url)
.then(d => d.json());
}
getAll(){
return this.bucket_list_promise;
}
}
然后
import toDoStore from './stores/todoStore'
class BucketApp extends React.Component {
constructor(props) {
super(props);
this.state = {
loadingData: true,
bucket_list: null
};
}
componentWillMount(){
toDoStore.getAll().then(result => {
this.setState({ bucket_list: result, loadingData: false })
})
}
答案 2 :(得分:0)
我想这是因为你的组件在结束异步提取之前呈现自己。换句话说,您未定义,并且在完成fetch
后(当您的商店更新时)获得结果时,您的组件不会更新。您可以应用上述技术,也可以使用Redux。在Redux中,如果存储更新,则会导致以某种方式与Redux存储连接的所有组件的更新。
答案 3 :(得分:0)
为解决此问题,我在组件状态上加载了初始数据,并在承诺被解决后侦听了componentDidMount上的发射以更新状态。下面是带有您的代码的示例。
//存储
import EventEmitter from "events";
let initState = {
id: 123,
name: "Hi",
isCompleted: false,
loadingData: true
};
class BucketlistStore extends EventEmitter {
constructor() {
super();
fetch(url)
.then(d => d.json())
.then(d => {
const { id, name, isCompleted } = d;
initState = { id, name, isCompleted, loadingData: false };
this.emit("updated");
});
}
getAll() {
return initState;
}
}
export default new BucketlistStore();
//组件
import React, { Component } from "react";
import toDoStore from "./stores/todoStore";
class BucketApp extends Component {
constructor(props) {
super(props);
this.state = toDoStore.getAll();
}
updateState = () => {
const { id, name, isCompleted, loadingData } = toDoStore.getAll();
this.setState({ id, name, isCompleted, loadingData });
};
componentWillMount() {
toDoStore.on("updated", this.updateState);
}
componentWillUnmount(){
toDoStore.off("updated", this.updateState);
}
render() {
const { id, name, isCompleted, loadingData } = this.state;
if (loadingData) return <p>Loading...</p>;
return null; //your code
}
}