场景相对简单:我们在远程服务器上进行了长时间运行的按需计算。我们想记住结果。即使我们从远程资源异步获取,这也不是副作用,因为我们只是希望将此计算的结果显示给用户,我们绝对不想在每次渲染时都这样做。
问题:React.useMemo 似乎不直接支持 Typescript 的 async/await 并且会返回一个 promise:
//returns a promise:
let myMemoizedResult = React.useMemo(() => myLongAsyncFunction(args), [args])
//also returns a promise:
let myMemoizedResult = React.useMemo(() => (async () => await myLongAsyncFunction(args)), [args])
Run Code Online (Sandbox Code Playgroud)
等待异步函数的结果并使用 React.useMemo 记住结果的正确方法是什么?我已经使用普通 JS 的常规承诺,但在这些类型的情况下仍然与它们斗争。
我尝试过其他方法,例如 memoize-one,但问题似乎是this由于 React 函数组件的工作方式导致上下文发生了变化,从而破坏了 memoization,这就是我尝试使用 React.useMemo 的原因。
也许我正在尝试在此处的圆孔中安装一个方钉-如果是这种情况,也最好知道这一点。现在我可能只是要推出我自己的记忆功能。
编辑:我认为部分原因是我在 memoize-one 上犯了一个不同的愚蠢错误,但我仍然有兴趣知道这里的答案是 React.memo。
这是一个片段 - 这个想法不是直接在渲染方法中使用记忆化的结果,而是作为以事件驱动的方式引用的东西,即在计算按钮单击上。
export const MyComponent: React.FC = () => {
let [arg, setArg] = React.useState('100');
let [result, setResult] = React.useState('Not yet calculated');
//My hang up …Run Code Online (Sandbox Code Playgroud) 有没有办法在类组件的情况下使用这个钩子或它的一些类似 React API 的东西?
我想知道,我应该在类组件的情况下使用一些第三方备忘录助手(例如lodash memo、memoizeOne等),还是存在一些用于类组件的官方反应 API 方式。
谢谢你的帮助。
聚苯乙烯
我想在改变孩子的情况下生成 uuid。
使用 SFC 组件我可以像这样使用 useMemo
const keyValue = useMemo(() => uuid()(), [children])
Run Code Online (Sandbox Code Playgroud)
但是如何在没有任何第三方等的情况下为基于类的组件实现相同的效果。
PPS 我没有使用 Redux 等,仅使用纯 React.js
我有这个错误:
src/index.js 第 9:36 行:作为 value prop 传递给 Context 提供程序的对象(第 9 行)每次渲染都会发生变化。要解决此问题,请考虑将其包装在 useMemo 钩子中 React/jsx-no-constructed-context-values
我不确定useMemo在这种情况下如何使用。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import FirebaseContext from './context/firebase';
import { firebase, FieldValue } from './lib/firebase';
import './styles/app.css';
ReactDOM.render(
<FirebaseContext.Provider value={{ firebase, FieldValue }}>
<App />
</FirebaseContext.Provider>,
document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud) 我试图在条件语句中使用反应钩子,不幸的是,反应给你几乎所有钩子的错误,并且它的意图按照钩子哲学。
然后我在 else 语句中尝试了 useMemo 钩子,并且没有错误。我用谷歌搜索了这个差异,但没有发现任何有希望的东西。
我的问题是,useMemo 是您可以在条件语句中使用 useMemo 的例外情况吗?
我正在创建一个组件,该组件将保存动态元素列表,出于样式原因,我需要将每个部分的标题保留在粘性导航菜单中。当用户上下滚动部分列表时,我需要应用样式规则,并将菜单导航中的同一部分带入视图,因此我尝试将scrollIntoView与菜单部分引用一起使用。
我的内部工作和逻辑似乎按预期工作,但是存在一个问题 - 除非我检查或在页面上使用刷新,否则scrollIntoView的函数不会在每次状态更改时执行
const scrollTo = (ref) => {
ref.current.scrollIntoView({ behavior: "smooth", inline: "center" });
};
Run Code Online (Sandbox Code Playgroud)
为了简单起见,我已将我的工作添加到此codesandbox中
任何帮助将不胜感激,因为我已经没有想法了。
谢谢
编辑:
如果我从scrollIntoViewOptions选项中删除行为参数中的“smooth”选项,滚动行为似乎会按预期工作。然而它看起来确实很神经质。
const scrollToMenu = (ref) => {
ref.current.scrollIntoView({ inline: "center", });
};
Run Code Online (Sandbox Code Playgroud) reactjs js-scrollintoview react-ref react-usememo react-scroll
我怎样才能记住我的rawTranscript变量,这样它就不会触发useEffect下面的函数,从而触发昂贵的transcriptParser函数?我一直在尝试很多不同的方法,但事实上,我使用 redux-hook ( useAppSelector) 从存储中捕获数据意味着我无法使用空依赖项 useEffect 进行初始安装(钩子不能位于内部)使用效果)。出于同样的原因,我似乎也无法用useAppSelector任何一个来包装。useMemo
关于如何记住变量rawTranscript以便它不会重新触发的任何想法useEffect?
useMemo在, ,useEffect中使用 redux-hook 时出错useCallback:
React Hook“useAppSelector”无法在回调内调用。React Hooks 必须在 React 函数组件或自定义 React Hook 函数中调用。
成分
const TranscriptCardController = (): JSX.Element => {
const dispatch = useAppDispatch();
// how to memoize rawTranscript?
const rawTranscript = useAppSelector(selectRawTranscript);
const parsedTranscript = useAppSelector(selectParsedTranscript);
useEffect(() => {
const parsedResult = transcriptParser(rawTranscript, undefined, 0.9);
dispatch(updateParsedTranscript(parsedResult));
}, [dispatch, rawTranscript]);
// ... …Run Code Online (Sandbox Code Playgroud) 我正在使用 useMemo 挂钩来渲染地图项目。我向 useMemo 挂钩添加了 items 参数,根据项目更改它将呈现。但是改变加载状态和items发生变化,Item自定义组件会渲染两次。我在使用 useMemo 钩子时是否犯了任何错误,请纠正我。
Home:
import React, { useState, useEffect, useMemo } from "react";
import Item from "./Item";
const array = [1];
const newArray = [4];
const Home = () => {
const [items, setItems] = useState(array);
const [loading, setLoading] = useState(false);
const [dataChange, setDataChange] = useState(1);
const renderItems = (item, index) => {
return (
<div key={item}>
<Item id={item}></Item>
</div>
);
};
useEffect(() => {
if (dataChange === 2) {
setLoading(true);
setTimeout(() => { …Run Code Online (Sandbox Code Playgroud) 我有两个“昂贵”的函数,我想在我的反应应用程序中记住它们,因为它们需要很长时间才能渲染。昂贵的函数用在数组映射中。我想记住数组映射的每个结果,这样如果数组的一个元素发生更改,只有该元素的昂贵函数将被重新计算。(并且要独立地记住昂贵的函数,因为有时只需要重新计算一个函数。)我正在努力解决如何记住并传递当前数组值的问题。
这是工作演示,没有记忆:
import React, { useMemo, useState } from "react";
const input = ["apple", "banana", "cherry", "durian", "elderberry", "apple"];
export default function App() {
const output = input.map((msg, key) => createItem(msg, key));
return <div className="App">{output}</div>;
}
const createItem = (message, key) => { // expensive function 1
console.log("in createItem:", key, message);
return (
<div key={key}>
<strong>{"Message " + (1 + key)}: </strong>
{message} =>{" "}
<span
id={"preview-" + key}
dangerouslySetInnerHTML={{ __html: msgSub(message) }}
/>
</div>
);
};
const msgSub = …Run Code Online (Sandbox Code Playgroud) 我有一个子组件,它位于父组件的循环内。当子组件之一更新父组件的状态时,它会重新渲染所有子组件,因为它是循环的。我怎样才能避免每次迭代的重新渲染。
function Parent() {
const [selectedChild, setSelectedChild] = useState([]);
const onChangeHandle = (event, id) => {
const checked = event.target.checked;
let updatedArray = [...selectedChild];
if(checked){
if(!selectedChild.includes(id)){
updatedArray.push(id);
}
}
else{
var index = updatedArray.indexOf(id)
if (index !== -1) {
updatedArray.splice(index, 1);
}
}
setSelectedChild(updatedArray);
}
const dummy = (id) => {
return selectedChild.includes(id);
}
return (
<div>
<table>
<tbody>
{[1,2,3].map((value, index) => {
return (
<Child
key={index}
index={index}
value={value}
handle={onChangeHandle}
isSelected={dummy}
/>
)
})}
</tbody>
</table>
<div>
{selectedChild}
</div>
</div>) …Run Code Online (Sandbox Code Playgroud) MUIsx的 prop对于速度和代码可读性很有用(合理),但它可能会导致许多不必要的重新渲染(这会导致性能下降)。sx
所以我想知道是否有办法添加 useMemo 包装版本的 MUIsx道具。我将如何扩展 MUI 来实现这一目标?
这是我的意思的一个简化示例。
基地情况:
const MyComponent = () => {
return
<>
<Box sx={{color: "red"}}> I am a bit static </Box>
<Box sx={{width: window.innerWidth + "px"}}> I am so dynamic! </Box>
</>
};
Run Code Online (Sandbox Code Playgroud)
这将是(在本例中是过度的)优化:
const MyComponent = () => {
const boxStyle = useMemo(() => ({color: "red"}), [])
return
<>
<Box sx={boxStyle}> I am a bit static </Box>
<Box sx={{width: window.innerWidth + "px"}}> I am so dynamic! …Run Code Online (Sandbox Code Playgroud) react-usememo ×10
reactjs ×9
react-hooks ×4
javascript ×2
async-await ×1
css ×1
material-ui ×1
memoization ×1
react-redux ×1
react-ref ×1
react-scroll ×1
reselect ×1
sx ×1