首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >跨多个组件重新选择只适用于deepEqual检查

跨多个组件重新选择只适用于deepEqual检查
EN

Stack Overflow用户
提问于 2018-03-15 13:33:14
回答 1查看 1.2K关注 0票数 0

我用各种方法测试过..。不过,它不起作用。我好像没做错什么

  • 与重新选择的文档完全相同的代码
  • redux存储已全部规范化。
  • 减速器都是不可变的。

从父组件中,我只传递一个带有id和子组件的道具,连接到redux,并使用选择器按id(从父组件)获得准确的项。

代码语言:javascript
复制
### This is what Parent components render looks like
render() {
    return (
      <div>
        <h4>Parent component</h4>
        {this.props.sessionWindow.tabs.map(tabId => 
           <ChildComponentHere key={tabId} tabId={tabId} />  
        )}
      </div>
    );
  }

### This is what Child component looks like
render() {
    const { sessionTab } = this.props  (this props is from connect() )
    <div>
        <Tab key={sessionTab.id} tab={sessionTab} />
      </div>
    ))
  }
### Selectors for across multiple components
const getTheTab = (state: any, ownProps: IOwnProps) => state.sessionWindows.sessionTab[ownProps.tabId];
const makeTheTabSelector = () =>
  createSelector(
    [getTheTab],
    (tab: object) => tab
  )
export const makeMapState = () => {
  const theTabSelector = makeTheTabSelector();
  const mapStateToProps = (state: any, props: IOwnProps) => {
    return {
      sessionTab: theTabSelector(state, props)
    }
  }
  return mapStateToProps
}

奇怪的解决方案:只需更改为深度平等检查。(从任何地方)

  • 使用深度相等的选择器会像预期的那样工作。
  • 在shouldComponentUpdate。使用_.isEqual也有效。

代码语言:javascript
复制
 1. const createDeepEqualSelector = createSelectorCreator(
       defaultMemoize,
       isEqual
    )
 2. if (!_isEqual(this.props, nextProps) || !_isEqual(this.state, nextState)){return true}

据我所知,我的redux总是不可变的,所以当某些东西发生变化时,它会产生新的引用(对象或数组),这就是为什么react重新呈现的原因。但是,当有100个项目,只有一个项目更改,只有组件与该改变的道具得到重新呈现。

为了实现这一点,我只传递id(只是字符串)。浅层相等(===)工作对吗?)使用这个id,得到准确的项。(大多数组件得到相同的值输入,但很少组件得到不同的值输入)使用重新选择来回溯值。当某些内容更新,每个组件得到新的参考输入时,与回忆录值进行比较,并在某些内容明显更改时重新呈现。

这主要是我现在能想到的..。如果我必须使用_isEqual,为什么要使用重新选择??我很确定我漏掉了什么东西。有人能帮忙吗?

需要更多的澄清。(希望.)首先,我的redux数据结构类似于这个

代码语言:javascript
复制
sessionWindow: {
  byId: {  // window datas byId
    "windowId_111": {
      id: "windowId_111",
      incognito: false,
      tabs: [1,7,3,8,45,468,35,124] // this is for the order of sessionTab datas that this window Item has
    },
    "windowId_222": {
      id: "windowId_222",
        incognito: true,
        tabs: [2, 8, 333, 111]
    },{
      ... keep same data structure as above
    }
  },
  allIds: ["windowId_222", "windowId_111"] // this is for the order of sessionWindow datas
}
sessionTab: {  // I put all tab datas here. each sessionTab doesn't know which sessionWindow they are belong to
  "1": {
    id: 1
    title: "google",
    url: "www.google.com",
    active: false,
    ...more properties
  },
  "7": {
    id: 7
    title: "github",
    url: "www.github.com",
    active: true
  },{
    ...keep same data structure as above
  }
}

问题。1.当一小部分数据发生变化时,它会重新呈现所有其他组件。假设sessionTab有id 7的url和标题更改。在我的sessionTab减速器上,发出了“SessionTabUpdated”动作。

代码语言:javascript
复制
const updateSessionTab = (state, action) => {
  return {
    ...state,
    [action.tabId]: {
      ...state[action.tabId],
      title: action.payload.title,
      url: action.payload.url
    }
  }
}

没有什么是坏的。仅仅使用基本的重新选择并不会阻止其他组件被重新呈现。我必须使用深度相等版本来停止在没有数据更改的情况下重新呈现组件。

经过几天的挣扎,我开始认为问题可能来自于我的redux数据结构?因为即使我从sessionTab中更改了一项,它也总是会产生新的引用,比如{...state,changedTab‘It:{.},我不知道.

EN

Stack Overflow用户

回答已采纳

发布于 2018-03-19 03:26:57

选择器定义和使用的三个方面看起来有点奇怪:

  • getTheTab正在一次深入研究多个层次
  • makeTheTabSelector有一个“输出选择器”,它只返回给定的值,这意味着它与getTheTab相同
  • mapState中,将整个props对象传递给theTabSelector(state, props)

我建议试一试,看看会发生什么:

代码语言:javascript
复制
const selectSessionWindows = state => state.sessionWindows;

const selectSessionTabs = createSelector(
    [selectSessionWindows],
    sessionWindows => sessionWindows.sessionTab
);

const makeTheTabSelector = () => {
    const selectTabById = createSelector(
        [selectSessionTabs, (state, tabId) => tabId],
        (sessionTabs, tabId) => sessionTabs[tabId]
    );
    return selectTabById;
}

export const makeMapState() => {
 const theTabSelector = makeTheTabSelector();
  const mapStateToProps = (state: any, props: IOwnProps) => {
    return {
      sessionTab: theTabSelector(state, props.tabId)
    }
  }
  return mapStateToProps
}

不能保证能解决问题,但值得一试。

您可能还想尝试使用一些devtool实用程序来告诉您组件为什么要重新呈现。我在Redux加载项目录Redux加载项目录部分中有几个这样的工具的链接。

希望这能让你解决问题。不管是哪种方式,留下评论并告诉我。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49300839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档