我对 DOMnode.getBoundingClientRect() 有问题,因为返回的数据不一致。我正在使用windows.onload(由于缺乏更好的选择)来触发我的函数,该函数需要一个getBoundingClientRect().height元素来对其进行一些计算。
问题是,元素的高度并不总是一致的。window.onload据我所知,甚至应该在页面生命周期中最后触发,并且内容、样式表和外部资源都应该在那时加载,但是页面显然仍然没有正确呈现,因为我有时会得到像 400 这样的高度值、528、630,有时对于我要读取的元素来说是正确的(700)。
想法?
是否有其他方法可以检测 a div(或页面)何时已完全呈现?
我的组件似乎进入了无限循环,我找不到原因。我正在使用useEffect和useState挂钩,但事实并非如此。对于想要将其标记为重复的任何人:请仔细阅读问题。这种无休止的重新渲染循环场景仅在以下情况下发生:
mousemove在之后触发事件(为了清楚起见,我省略了mousedown/mouseup处理程序,但它们本质上与mousemove处理程序相同,触发对每个订阅的回调的调用。这是一个示例,但请注意它可能会导致无限循环并强制您关闭浏览器选项卡 Codesandbox: https ://codesandbox.io/s/infiniteloopissue-lynhw ? file =/ index.js
我正在使用在事件上Map.forEach触发setState任何订阅者的mousemove。(您可以在下面看到相关代码),我正在使用useEffect此“更新事件”订阅/取消订阅
“修复”问题的一件事如下 - 检查参考点评论(在鼠标使用者下方)。如果回调作为useCallback钩子的依赖项被删除,则一切正常。但这并不好,因为在这个例子中,我们显然只是将数据提取到状态中,但该callback函数可能依赖于其他状态,在这种情况下它不起作用。回调需要是可变的。
我的猜测是反应以某种方式设法在.forEach完成它的迭代之前重新渲染,在这种情况下它会取消订阅(从而删除密钥),然后重新订阅(从而再次添加它)触发另一个回调,然后触发另一个回调取消订阅/重新订阅,我们进入一个循环。但这应该不可能吧?我的意思是 javascript 假设阻塞单线程,如何/为什么在 forEach 循环中间重新渲染?
另外,是否有人对如何“订阅” amousemove并运行回调有更好的想法。最近EventEmitter在一些后端代码中看到了一些,但不是很熟悉。我也不确定这是否可以解决这里的问题,更新时反应的问题优先于等待主线程完成.forEach循环(至少我认为是这样)
基础很简单:
const App = () => {
return (
<MouseProvider>
<Component />
</MouseProvider>
)
}
Run Code Online (Sandbox Code Playgroud)
const Component = props => {
const …Run Code Online (Sandbox Code Playgroud) 我想使用“全局函数”,因为我的许多组件中缺乏更好的词,例如 80% 或更多。这个函数有点像翻译成语言的消息存储库,所以我会传递它作为例子SM(1245, 'eng'),它应该返回英语消息。
function SM(messageID, language){
return languageMap.get(language).get(messageID);
}
Run Code Online (Sandbox Code Playgroud)
该函数的作用几乎类似于地图地图的 getter,但是,用于填充这些地图的数据位于服务器上。
如果我理解正确,从文件导出函数,然后将其导入每个组件将多次“重新运行”函数的脚本文件,导致多次服务器调用来获取数据,我想避免这种情况当许多用户开始使用许多组件时,不要对我的服务器进行 DDOS。
我该怎么办?
编辑:我还想过将其作为我的 App.js 主组件类的一部分,但随后我必须通过长链的道具将其传递下去,我真的很想避免这种情况。
编辑2:尝试了评论中的建议,以正常方式向 Index.html 添加一个简单的 .js 文件,在那里定义一个函数并在我需要的地方使用它,这是一种很好的老式方式。设法做到了这一点,但问题是,以这种方式添加的函数在 React 应用程序的“编译时”无法访问,或者更确切地说,我在评估 .jsx 表达式时无法使用它。
是否真的没有简单的方法来制作一个用于实用功能但包含数据并且不会为每个组件调用的文件,也不会通过长长的道具链?
对于我的死,在过去的三个小时里我无法弄清楚这一点,我非常沮丧,所以如果我听起来太咄咄逼人,我提前道歉。
我想要的只是能够为我的组件定义一个打字稿接口,并让它扩展任何组件使用的默认接口,以避免必须在我自己的接口中声明每个该死的默认属性,例如 ,className等等onClick。
我有这个组件:
import React, { useEffect, useRef, FunctionComponent } from 'react'
import './style.scss'
interface ISideProps {
wideModeEnabled: boolean
toggleWideMode
setFocus
}
const AppLayoutSide: FunctionComponent<ISideProps> = (props) => {
const ref = useRef() as any
...
...
etc.
return <div {...props} />
}
Run Code Online (Sandbox Code Playgroud)
现在这个组件没有错误,至少打字稿没有给出任何错误。但是如果我尝试在另一个组件中渲染这个组件,例如这样:
const otherComponent = () => {
return (
<div className='content'>
<Menu />
<Main />
<Side
className={'whatever'} //Typescript error happens here
wideModeEnabled={wideMode}
toggleWideMode={toggleWideMode}
setFocus={setSideFocus}
/>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
错误说:
输入 '{ 类名:字符串;WideModeEnabled:布尔值;切换宽模式:()=>无效;setFocus: …
不太确定这是否可行,但由于我讨厌 Typescript 并且它使我的编码变得困难,所以我想我会问一下以确保确定。
interface ISomeInterface {
handler: () => {}
[key: string]: string
}
Run Code Online (Sandbox Code Playgroud)
问题显然是,它handler是一个() => {}而不是字符串,所以打字稿会抛出错误。有可能以某种方式使这项工作有效吗?
在主题中,该接口应该由 a 使用React.Context,并且由于 需要默认值React.createContext(/* requires default here */),所以我需要给它一个与该接口匹配的对象。当我尝试传递对象文字时:
React.createContext({handler: () => {throw new Error('using default context')}})
Run Code Online (Sandbox Code Playgroud)
Typescript 正在引起骚动,它说{handler: () => never} cannot be assigned to {handler: () => {}}有什么方法可以让这个界面变得合理吗?我尝试使接口实现() => any,仍然不起作用,它需要显式never。
所以我做了一些改变,即:
interface IFormContext {
$handleChange: (key?, val?) => void
$registerField: (key?) => void
[key: string]: …Run Code Online (Sandbox Code Playgroud) 我将假定这是某种兼容性问题。一切都可以在chrome中完美运行,但是在Firefox中,它<canvas>根本无法画任何东西。
function drawStage(stageNum) {
var cap = canvasArray.length; //keeps the canvasElements
var i;
var stageImages = images["stage" + stageNum];
var stageDimensions = imageDimensions["stage" + stageNum];
//console.log("Cap is: " + cap);
for (i = 0; i < cap; i++) {
var canvas = document.getElementById(canvasArray[i]);
var canvasContext = canvas.getContext("2d");
var image = document.getElementById(stageImages[i]);
canvasContext.clearRect(0, 0, 1280, 1280);
canvasContext.drawImage(image, stageDimensions[i][0], stageDimensions[i][1], stageDimensions[i][2], stageDimensions[i][3]);
//document.getElementById(zIndexes[i][0]).style["z-index"] = zIndexes[i][stageNum];
//console.log(document.getElementById(zIndexes[i][0]).id);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑: 这是我制作的“测试”代码示例的保管箱链接,它更简单,1张图像,1个画布,1个div,相似(实际上是相同的)脚本,但仍无法在Firefox中使用,但可以在chrome中使用。如果您可以在那里解决问题,那么这也将得到解决。
更新:数组在下面,根据请求,它们是不同元素/坐标的简单输入。不过,我向您保证,数组本身没有问题,在chrome中一切正常。该函数中有关DrawImage()方法的某些问题引起了我要说的问题。(数组下方的进一步说明)
images是<img>元素的(全局)id数组。
var images = { …Run Code Online (Sandbox Code Playgroud) javascript ×4
reactjs ×4
typescript ×2
canvas ×1
dom ×1
drawimage ×1
firefox ×1
interface ×1
jsx ×1