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')始终为真,租船人每次都会得到渲染


也许我遗漏了一些重要的东西?

这是因为您没有提供任何函数来测试道具的平等性;因此执行
比较

因此,如果您的
选择器
返回一个新的数组/对象(我假设是这样的,尤其是当您使用数组/对象销毁来填充选择器返回值时);肤浅的平等总是会返回错误;然后组件将重新渲染

我建议使用from
lodash
对等式进行测试

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 is
react.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
    )