调用外部函数时如何重新渲染 React 组件?
How to re-render React Component when outside function is called?
我希望能够接收 mqtt 消息并将它们显示在网络应用程序上。我正在使用 AWS Amplify 的 PubSub,函数调用发生在 class 组件之外。我无法从它外部的函数直接访问任何实例 functions/properties,但我需要一些方法来触发 setState 更改,以便可以重新呈现 Web 应用程序,对吗?
我试过直接从 React class 调用函数,但仍然没有重新渲染。我试过制作一个外部变量,将收到的消息存储在其中,然后从 React class 访问该变量,但仍然没有触发。然后我研究并发现我可以每隔几秒强制重新渲染一次,但读到应该避免做这样的事情。我应该使用 ComponentDidMount 和 setState 函数,但并不真正理解如何让它工作。
同样,我真正想做的是获取消息并更新网络应用程序以显示新消息。听起来很简单,但我被卡住了。
import...
var itemsArr = [];
function subscribe() {
// SETUP STUFF
Amplify.configure({
...
});
Amplify.addPluggable(new AWSIoTProvider({
...
}));
// ACTUAL SUBSCRIBE FUNCTION
Amplify.PubSub.subscribe('item/list').subscribe({
next: data => {
// LOG DATA
console.log('Message received', data);
// GET NAMES OF ITEMS
var lineItems = data.value.payload.lineItems;
lineItems.forEach(item => itemsArr.push(item.name));
console.log('Items Ordered', itemsArr);
// THIS FUNCTION CALL TRIGGERS AN ERROR
// CANT ACCESS THIS INSTANCE FUNCTION
this.update(itemsArr);
},
error: error => console.error(error),
close: () => console.log('Done'),
});
}
// REACT COMPONENT
class App extends Component {
constructor(props){
super(props);
this.state = {
items:null,
};
}
// THOUGHT I COULD USE THIS TO UPDATE STATE
// TO TRIGGER A RE-RENDER
update(stuff){
this.setState({items: stuff});
}
render() {
// THINK SUBSCRIBE METHOD CALL SHOULDN'T BE HERE
// ON RE-RENDER, KEEPS SUBSCRIBING AND GETTING
// SAME MESSAGE REPEATEDLY
subscribe();
console.log('items down here', itemsArr);
return (
<div className="App">
<h1>Test</h1>
<p>Check the console..</p>
<p>{itemsArr}</p>
</div>
);
}
}
export default App;
理想情况下,我希望在收到消息时显示项目列表的列,但我目前遇到错误 - "TypeError: Cannot read property 'update' of undefined" 因为 class 之外的订阅功能无法访问 class.
中的更新功能
将subscribe 方法放在App 组件中,这样你就可以调用它了。您可以在 componentDidMount 生命周期中调用 subscribe 方法在 App 组件第一次渲染后执行它(以获取项目)。然后,更新方法将 运行 this.setState() (将您的项目存储在状态中)导致 App 组件 re-render。因此 re-render,您的 this.state.items 将包含一些内容,并将显示在您的段落中。
class App extends Component {
constructor(props){
super(props);
this.state = {
items: [],
};
this.subscribe = this.subscribe.bind(this);
this.update = this.update.bind(this);
}
update(stuff){
this.setState({ items: stuff });
}
subscribe() {
// SETUP STUFF
Amplify.configure({
...
});
Amplify.addPluggable(new AWSIoTProvider({
...
}));
// ACTUAL SUBSCRIBE FUNCTION
Amplify.PubSub.subscribe('item/list').subscribe({
next: data => {
// LOG DATA
console.log('Message received', data);
// GET NAMES OF ITEMS
let itemsArr = [];
var lineItems = data.value.payload.lineItems;
lineItems.forEach(item => itemsArr.push(item.name));
console.log('Items Ordered' + [...itemsArr]);
this.update(itemsArr);
},
error: error => console.error(error),
close: () => console.log('Done'),
});
}
componentDidMount() {
this.subscribe();
}
render() {
console.log('items down here ' + [...this.state.items]);
return (
<div className="App">
<h1>Test</h1>
<p>Check the console..</p>
<p>{this.state.items !== undefined ? [...this.state.items] : "Still empty"}</p>
</div>
);
}
}
export default App;
我希望能够接收 mqtt 消息并将它们显示在网络应用程序上。我正在使用 AWS Amplify 的 PubSub,函数调用发生在 class 组件之外。我无法从它外部的函数直接访问任何实例 functions/properties,但我需要一些方法来触发 setState 更改,以便可以重新呈现 Web 应用程序,对吗?
我试过直接从 React class 调用函数,但仍然没有重新渲染。我试过制作一个外部变量,将收到的消息存储在其中,然后从 React class 访问该变量,但仍然没有触发。然后我研究并发现我可以每隔几秒强制重新渲染一次,但读到应该避免做这样的事情。我应该使用 ComponentDidMount 和 setState 函数,但并不真正理解如何让它工作。
同样,我真正想做的是获取消息并更新网络应用程序以显示新消息。听起来很简单,但我被卡住了。
import...
var itemsArr = [];
function subscribe() {
// SETUP STUFF
Amplify.configure({
...
});
Amplify.addPluggable(new AWSIoTProvider({
...
}));
// ACTUAL SUBSCRIBE FUNCTION
Amplify.PubSub.subscribe('item/list').subscribe({
next: data => {
// LOG DATA
console.log('Message received', data);
// GET NAMES OF ITEMS
var lineItems = data.value.payload.lineItems;
lineItems.forEach(item => itemsArr.push(item.name));
console.log('Items Ordered', itemsArr);
// THIS FUNCTION CALL TRIGGERS AN ERROR
// CANT ACCESS THIS INSTANCE FUNCTION
this.update(itemsArr);
},
error: error => console.error(error),
close: () => console.log('Done'),
});
}
// REACT COMPONENT
class App extends Component {
constructor(props){
super(props);
this.state = {
items:null,
};
}
// THOUGHT I COULD USE THIS TO UPDATE STATE
// TO TRIGGER A RE-RENDER
update(stuff){
this.setState({items: stuff});
}
render() {
// THINK SUBSCRIBE METHOD CALL SHOULDN'T BE HERE
// ON RE-RENDER, KEEPS SUBSCRIBING AND GETTING
// SAME MESSAGE REPEATEDLY
subscribe();
console.log('items down here', itemsArr);
return (
<div className="App">
<h1>Test</h1>
<p>Check the console..</p>
<p>{itemsArr}</p>
</div>
);
}
}
export default App;
理想情况下,我希望在收到消息时显示项目列表的列,但我目前遇到错误 - "TypeError: Cannot read property 'update' of undefined" 因为 class 之外的订阅功能无法访问 class.
中的更新功能将subscribe 方法放在App 组件中,这样你就可以调用它了。您可以在 componentDidMount 生命周期中调用 subscribe 方法在 App 组件第一次渲染后执行它(以获取项目)。然后,更新方法将 运行 this.setState() (将您的项目存储在状态中)导致 App 组件 re-render。因此 re-render,您的 this.state.items 将包含一些内容,并将显示在您的段落中。
class App extends Component {
constructor(props){
super(props);
this.state = {
items: [],
};
this.subscribe = this.subscribe.bind(this);
this.update = this.update.bind(this);
}
update(stuff){
this.setState({ items: stuff });
}
subscribe() {
// SETUP STUFF
Amplify.configure({
...
});
Amplify.addPluggable(new AWSIoTProvider({
...
}));
// ACTUAL SUBSCRIBE FUNCTION
Amplify.PubSub.subscribe('item/list').subscribe({
next: data => {
// LOG DATA
console.log('Message received', data);
// GET NAMES OF ITEMS
let itemsArr = [];
var lineItems = data.value.payload.lineItems;
lineItems.forEach(item => itemsArr.push(item.name));
console.log('Items Ordered' + [...itemsArr]);
this.update(itemsArr);
},
error: error => console.error(error),
close: () => console.log('Done'),
});
}
componentDidMount() {
this.subscribe();
}
render() {
console.log('items down here ' + [...this.state.items]);
return (
<div className="App">
<h1>Test</h1>
<p>Check the console..</p>
<p>{this.state.items !== undefined ? [...this.state.items] : "Still empty"}</p>
</div>
);
}
}
export default App;