我如何强制 React 组件从 javascript 文件刷新
How can i force a react component to refresh from a javascript file
我正在尝试让一个反应组件显示使用 websockets 从后端检索到的项目列表。然而,由于我的 websockets.js 文件在反应层次结构之外,因此列表实际上从未刷新,因此不会显示项目。
到目前为止,我尝试的是将 "projects" 的 public 数组添加到 websocketservice.js 文件,然后在我的 React 组件中引用此列表。然而,即使 websocket returns 具有其收集的值,它也永远不会刷新。
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.")
}
}
ProjectSelect.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 使用收集到的值更新列表,反应组件就会刷新并显示值列表
我会从 WebsocketInstance.createProject(this.state.projectname)
中取出 return 并做类似
const myData = WebsocketInstance.createProject(this.state.projectname);
this.setState({webSocitReturn: myData})
的事情
模式是更新state/props让它刷新。尝试尽可能多地投入反应 API 以获得所需的结果。
此外,请记住我放置的上述代码示例需要一些修改以解决异步问题。
编辑:如果这不起作用,这里是一篇关于套接字和反应的博客post。 https://blog.logrocket.com/beyond-rest-using-websockets-for-two-way-communication-in-your-react-app-884eff6655f5
我通过给我的 websocketinstance 一个回调方法来解决这个问题:
projectselect.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)
}
}
我正在尝试让一个反应组件显示使用 websockets 从后端检索到的项目列表。然而,由于我的 websockets.js 文件在反应层次结构之外,因此列表实际上从未刷新,因此不会显示项目。
到目前为止,我尝试的是将 "projects" 的 public 数组添加到 websocketservice.js 文件,然后在我的 React 组件中引用此列表。然而,即使 websocket returns 具有其收集的值,它也永远不会刷新。
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.")
}
}
ProjectSelect.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 使用收集到的值更新列表,反应组件就会刷新并显示值列表
我会从 WebsocketInstance.createProject(this.state.projectname)
中取出 return 并做类似
const myData = WebsocketInstance.createProject(this.state.projectname);
this.setState({webSocitReturn: myData})
模式是更新state/props让它刷新。尝试尽可能多地投入反应 API 以获得所需的结果。
此外,请记住我放置的上述代码示例需要一些修改以解决异步问题。
编辑:如果这不起作用,这里是一篇关于套接字和反应的博客post。 https://blog.logrocket.com/beyond-rest-using-websockets-for-two-way-communication-in-your-react-app-884eff6655f5
我通过给我的 websocketinstance 一个回调方法来解决这个问题:
projectselect.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)
}
}