Javascript 在不改变道具的情况下,反应记忆化组件重新启动
我无法记忆我的组件Javascript 在不改变道具的情况下,反应记忆化组件重新启动,javascript,reactjs,Javascript,Reactjs,我无法记忆我的组件 const Miscellaneous = () => { const dispatch = useDispatch<DispFn>(); const brokers = useSelector(getSettingsMiscBrokers); const charterers = useSelector(getSettingsMiscCharterers); if (window.charterers) {
const Miscellaneous = () => {
const dispatch = useDispatch<DispFn>();
const brokers = useSelector(getSettingsMiscBrokers);
const charterers = useSelector(getSettingsMiscCharterers);
if (window.charterers) {
console.log(window.charterers === charterers, 'check equality charterers');
} else {
window.charterers = charterers;
}
useEffect(() => {
dispatch(fetchBrokersList());
}, []);
return (
<AclShowSectionWrapper sectionName={CHARTER_SETTINGS}>
<div className="fb" style={{ padding: '1rem 2rem 2rem 2rem' }}>
<Row className="bigHorizontalScroll" grow noWrap>
<Col {...colGrid}>
<Charterers charterers={charterers} />
</Col>
<Col {...colGrid}>
<Brokers brokers={brokers} />
</Col>
</Row>
</div>
</AclShowSectionWrapper>
);
};
export const Charterers = React.memo((props: IProps) => {
console.log('charterers');
return (
<div>{*some stuff here*}</div>
);
});
所以问题是,当我在brokers表中进行更改时,这只会导致brokers部分中的存储更改,并且这条语句console.log(window.charters===charters,'check equality charters')始终为真,租船人每次都会得到渲染
也许我遗漏了一些重要的东西?这是因为您没有提供任何函数来测试道具的平等性;因此执行
浅比较
因此,如果您的选择器
返回一个新的数组/对象(我假设是这样的,尤其是当您使用数组/对象销毁来填充选择器返回值时);肤浅的平等总是会返回错误;然后组件将重新渲染
我建议使用fromlodash
对等式进行测试
import { isEqual } from 'lodash';
Const MemoizedComponent = React.memo(Component, isEqual);
编辑:
您是这样使用选择器的:使用选择器(selectorCreator)
它应该是useSelector(selectorCreator())
引自
如上图所示,将useSelector与内联选择器一起使用时
每当创建组件时,都会创建选择器的实例
渲染
此外,createSelector
使用选择器调用createSelectorCreator
;每次都返回一个新函数,每次都用一个新函数调用函数
export const createSelector = /* #__PURE__ */ createSelectorCreator(defaultMemoize)
export function createSelectorCreator(memoize, ...memoizeOptions) {
return (...funcs) => {
let recomputations = 0
const resultFunc = funcs.pop()
const dependencies = getDependencies(funcs)
const memoizedResultFunc = memoize(
function () {
recomputations++
// apply arguments instead of spreading for performance.
return resultFunc.apply(null, arguments)
},
...memoizeOptions
)
您可以看到我发布了一个答案,说明了使用React.memo时的主要问题。对于进一步的调试,如果这不能解决您的问题;请提供您的GetSettingsMiscCharters
Selector或刚刚看到它。请忽略我之前的评论这是我不久前在React.memo上写的答案。它可以帮助您调试问题。TLDR isreact.memo
不能用来防止重新渲染,因为我在这种情况下使用了“重新选择”,在这种情况下,它总是返回相同的对象(例如引用)。window.charters===charters将是真实的,只要看到您使用的useSelector如下:useSelector(selectorCreator)
;我认为它是使用选择器(selectorCreator())
。更新我的答案;但是,如果有人错过了浅层相等答案,则浅层相等答案将保持有效请检查此链接,您可以使用有效的重新选择用法和useSelectorA函数调用,该函数调用将返回一个函数,并将始终创建一个新函数(每次都创建一个新引用)。我已经遇到了这个问题。或者使用第二个参数(equality func)
export const createSelector = /* #__PURE__ */ createSelectorCreator(defaultMemoize)
export function createSelectorCreator(memoize, ...memoizeOptions) {
return (...funcs) => {
let recomputations = 0
const resultFunc = funcs.pop()
const dependencies = getDependencies(funcs)
const memoizedResultFunc = memoize(
function () {
recomputations++
// apply arguments instead of spreading for performance.
return resultFunc.apply(null, arguments)
},
...memoizeOptions
)