试图与React新的Hooks和ActionCable相处,但是遇到了这样的问题:尝试发送状态时,我无法在Rails中获得正确的数据。
我尝试在完成send()
后立即使用setState()
方法并发送我的更新数据,但是由于某些原因,在Rails部分接收的数据已旧。
例如,如果我在输入中输入“ Example”,那么我会在Rails端看到“ {{data” =>“ Exampl”}。我认为数据更新状态要晚于请求的执行时间。
如果我send()
的{{1}}值一切正常
因此,我尝试使用新的e.target.value
挂钩并在那里发送数据。但是渲染页面时我只能得到数据。之后,我什么也没得到,有时会收到错误useEffect()
。似乎效果钩子太早发送数据了。
我对Hooks和WebSocket还是很陌生。希望在这里获得任何帮助。我可以共享Rails代码,但是只有一个接收方,没有别的。
第一例:
RuntimeError - Unable to find subscription with an identifier
尝试使用useEffect并将import React, { useState, useEffect } from "react"
import ActionCable from 'actioncable'
function Component(props) {
const [data, setData] = useState("");
const cable = ActionCable.createConsumer('ws://localhost:3000/cable');
const sub = cable.subscriptions.create('DataChannel');
const handleChange = (e) => {
setData(e.target.value)
sub.send({ data });
}
return (
<input value={data} onChange={handleChange}/>
)
}
移到那里:
send()
我很想找到一种正确使用React和ActionCable的方法。并尽可能使用钩子。
答案 0 :(得分:0)
您可以像这样在根组件上注册电缆:
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from scipy.integrate import solve_bvp
def fun(x, y):
return np.vstack([y[1], y[2], y[3], np.ones(y.shape[1])])
def bc(ya, yb) :
return np.array([ya[0], ya[1], yb[0], yb[1]])
xmesh = np.linspace(0, 10, 100)
y = np.zeros((4, len(xmesh)))
sol = solve_bvp(fun, bc, xmesh, y)
plt.figure()
for i in range(4):
plt.plot(xmesh, sol.sol(xmesh)[i], label = str(i+1))
plt.legend()
因此它将用作全局变量;
,然后在要创建频道并发送数据的任何组件中:
import actionCable from 'actioncable';
(function() {
window.CableApp || (window.CableApp = {});
CableApp.cable = actionCable.createConsumer('ws://localhost:3000/cable')
}).call(this);`
答案 1 :(得分:0)
我正在尝试一种类似于Oleg的方法,但是在动作电缆内部无法setChannel
创建订阅回调。我必须在回调之外setChannel
内但在useEffect挂钩内。以下是对我有用的解决方案。
index.js
import React, { createContext } from 'react'
import actionCable from 'actioncable'
... omitted other imports
const CableApp = {}
CableApp.cable = actionCable.createConsumer('ws://localhost:3000/cable')
export const ActionCableContext = createContext()
ReactDOM.render(
<Router>
... omitted other providers
<ActionCableContext.Provider value={CableApp.cable}>
<App />
</ActionCableContext.Provider>
</Router>,
document.getElementById('root')
)
import React, { useState, useEffect, useContext } from 'react'
import { useParams } from 'react-router-dom'
... omitted code
const [channel, setChannel] = useState(null)
const { id } = useParams()
const cable = useContext(ActionCableContext)
useEffect(() => {
const channel = cable.subscriptions.create(
{
channel: 'MessagesChannel',
id: id,
},
{
received: (data) => {
receiveMessage(data)
},
}
)
setChannel(channel)
return () => {
channel.unsubscribe()
}
}, [id])
const sendMessage = (content) => {
channel.send(content)
}
答案 2 :(得分:0)
您的问题在这里:
@echo off
rem run cmd with \u -for utf 16
setlocal EnableDelayedExpansion EnableExtensions
SET "SourceParentDir=C:\Export"
set back=%cd%
set "files="
set "originalPDF="
rem loop through subdirectories
for /d %%i in (%SourceParentDir%\*) do (
rem get filepath of master pdf
set "originalPDFpath=%%~i"
set "originalPDFpath=!originalPDFpath:~0,-1!.pdf"
rem get filename of master pdf
set "originalPDF=%%~nxi"
set "originalPDF=!originalPDF:~0,-1!.pdf"
rem traverse subdirectories
cd "%%i"
rem get list of pdf files
(for /R %%a in (*.pdf) do (
set "files=!files! "%%~fa""
)
rem combine pdf files
pdftk "!originalPDFpath!" !files! cat output "c:\test\!originalPDF!"
set "files="
)
)
cd %back%
setData 就像 setState 一样,状态只在渲染之后更新,即在函数退出之后。您发送的是当前数据而不是新数据。试试这个:
const handleChange = (e) => {
setData(e.target.value)
sub.send({ data });
}