javascript - 我如何强制反应组件从 javascript 文件中刷新
问题描述
我正在尝试获取一个反应组件来显示已使用 websockets 从后端检索到的项目列表。但是,由于我的 websockets.js 文件位于反应层次结构之外,因此列表实际上从未刷新,因此不会显示项目。
到目前为止,我尝试的是在 websocketservice.js 文件中添加一个公共的“项目”数组,然后在我的反应组件中引用这个列表。然而,即使 websocket 以其收集的值返回,它也永远不会刷新。
websocketservice.js
class WebSocketService{
projects = []
static getInstance() {
if(!WebSocketService.instance){
WebSocketService.instance = new WebSocketService();
}
return WebSocketService.instance;
}
constructor() {
this.socketRef = null;
}
connect() {
const path = 'ws://127.0.0.1:8000/ws/wspingpong/';
this.socketRef = new WebSocket(path);
this.socketRef.onopen = () => {
console.log('websocket opened');
this.sendTestMessage();
};
this.socketRef.onmessage = e => {
console.log("message recieved: " + e.data);
this.messageRecieved(e.data)
}
this.socketRef.onerror = e => {
console.log(e.onmessage);
}
this.socketRef.onclose = () => {
console.log('websocket is closed');
this.connect();
}
}
sendMessage(data){
try{
this.socketRef.send(JSON.stringify(...data))
}catch(err){
console.log(err.message)
}
}
messageRecieved(data) {
const parsedData = JSON.parse(data);
const command = parsedData.command;
if(command === "STC-test"){
console.log("succesfully recieved a testmessage from the server");
}
if(command === "STC-login"){
console.log("succesfully logged in, redirecting...")
console.log(parsedData.message)
this.loggedUser = {
username: parsedData.message["username"],
email: parsedData.message["email"]
}
history.push("/project")
}
if(command === "STC-getprojects"){
console.log(parsedData.message)
this.projects = parsedData.message
}
}
上面console.log(parsedData.message)
正确显示了项目列表
getProjects(){
console.log("getting projects....")
if(this.loggedUser != null){
var dict = [];
dict.push({
command: "CTS-getprojects",
message: ""
})
this.sendMessage(dict)
}else{
console.log("no user logged in, unable to retrieve projects.")
}
}
项目选择.tsx
export default class ProjectSelect extends React.Component<Iprops>{
constructor(props: Iprops) {
super(props)
}
render() {
return (
<div>
{
WebsocketInstance.loggedUser != null ?
<div>
<h3>ProjectSelect, welcome user: {WebsocketInstance.loggedUser.username}</h3>
{WebsocketInstance.projects.map((name: any) => <span>name: {name}</span>)}
<label>Project Name:</label>
<input onChange={e => this.setState({ projectname: e.target.value })}></input>
<button onClick={() => this.createProject()}>Create a new project</button>
</div>
:
null
}
</div>
)
}
createProject() {
WebsocketInstance.createProject(this.state.projectname)
}
编辑 尝试修复:
constructor(props: Iprops) {
super(props)
this.state = {
projectnames: []
}
this.setState({
projectnames: WebsocketInstance.projects
})
}
然后在我添加的渲染方法中:
{this.state.projectnames.map((name: any) => <span>name: {name}</span>)}
然而这并没有奏效
我的目标是,一旦 websocket 使用收集的值更新列表,react 组件就会刷新并显示值列表
解决方案
我设法通过给我的 websocketinstance 一个回调方法来解决这个问题:
项目选择.tsx
constructor(props: Iprops) {
super(props)
this.state = {
projectnames: [],
projectname: ""
}
WebsocketInstance.callback = this.getProjectsCallback
WebsocketInstance.getProjects()
}
renderMessages = (messages:any) => {
return messages.map((message:any) => (
<div>
<span>{message["projectname"]}</span>
<button onClick={() => this.openProject(message["id"])}>Load project</button>
</div>
))
}
getProjectsCallback = (messages:any) => {
this.setState({
projectnames: messages
})
}
当从 websocket 调用回调并获得一个新列表时,我会更新状态并且 react 将自动重新渲染组件。
websocket.js
messageRecieved(data) {
const parsedData = JSON.parse(data);
const command = parsedData.command;
if(command === "STC-test"){
console.log("succesfully recieved a testmessage from the server");
}
if(command === "STC-login"){
console.log("succesfully logged in, redirecting...")
console.log(parsedData.message)
this.loggedUser = {
username: parsedData.message["username"],
email: parsedData.message["email"]
}
history.push("/project")
}
if(command === "STC-getprojects"){
console.log(parsedData.message)
this.callback(parsedData.message)
}
}
推荐阅读
- clojure - 带有外部绑定符号的 core.async go 块可以工作,但不能进行宏扩展
- date - 如何忽略空白以返回从列中返回最接近今天的日期?
- python - 将零更改为数组中最近的左侧非零邻居
- typo3 - TYPO3:微型网站上的新闻详细信息视图
- python-3.x - 有没有办法在 Raspbian 等 Linux 操作系统中模拟击键和鼠标点击?
- python - 在 Outlook 正文中调整 HTML 表格的大小不起作用
- android - 我无法从 Google Codelab 在 AndroidStudio 上打开项目
- flutter - 无法使用 AudioPlayer 包在 iOS 上播放来自 URL 的音频 - Flutter
- c# - 无法从 CouchDB 反序列化 Json
- python - 从文件夹安装 Python 模块