React Flux 通过 API 调用加载初始数据
React Flux Loading Initial Data via API Call
我已经在这个问题上停留了几个小时了。我想实现 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()
};
}
这很好用。我有一家商店,它基本上是我的 component
从中接收数据的 collection
。但是,现在我想从数据库中初始化数据。所以我更新了我的 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() returns undefined
。为什么会这样?我做错了什么?
由于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
中使用它以防止渲染(改为显示加载器)。
它 returns 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 })
})
}
我想这是因为你的组件在结束异步获取之前渲染了它自己。换句话说,你得到了未定义,并且当你在完成 fetch
(当你的商店更新时)后得到结果时,你的组件没有更新。您可以应用上述技术,或者您可以使用 Redux。在 Redux 中,如果存储被更新,它会导致以某种方式与 Redux 存储连接的所有组件的更新。
为了解决这个问题,我在我的组件状态上加载了初始数据,并在 componentDidMount 上监听 emit 以在解决 promise 时更新状态。下面是您的代码示例。
//商店
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
}
}
我已经在这个问题上停留了几个小时了。我想实现 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()
};
}
这很好用。我有一家商店,它基本上是我的 component
从中接收数据的 collection
。但是,现在我想从数据库中初始化数据。所以我更新了我的 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() returns undefined
。为什么会这样?我做错了什么?
由于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
中使用它以防止渲染(改为显示加载器)。
它 returns 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 })
})
}
我想这是因为你的组件在结束异步获取之前渲染了它自己。换句话说,你得到了未定义,并且当你在完成 fetch
(当你的商店更新时)后得到结果时,你的组件没有更新。您可以应用上述技术,或者您可以使用 Redux。在 Redux 中,如果存储被更新,它会导致以某种方式与 Redux 存储连接的所有组件的更新。
为了解决这个问题,我在我的组件状态上加载了初始数据,并在 componentDidMount 上监听 emit 以在解决 promise 时更新状态。下面是您的代码示例。
//商店
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
}
}