【问题标题】:alternative to innerRef when using hooks使用钩子时替代innerRef
【发布时间】:2019-05-03 04:23:09
【问题描述】:

我正在将基于类的组件转换为反应钩子。我对使用 ref 部分感到困惑。因为,我使用它的方式抱怨我The "innerRef" API has been removed in styled-components v4 in favor of React 16 ref forwarding, use "ref" instead like a typical component.

使用钩子时如何使其工作?

const Tabs = ({activeTab, children}) => {
  const [tabsElements, setTabsElements] = useState([])

  return (
    <TabsContext.TabProvider activeTab={activeTab}>
      <TabsContext.TabConsumer>
        {value => (
          <ReactTabs>
            <TabsContainer>
              <ListTabs>
                {value.context.tabs.map(tab => (
                  <TabTitleItem
                    key={tab.id}
                    onClick={value.context.onClick(tab)}
                    id={tab.id}
                    innerRef={tabElement => {
                      if (!tabsElements[tab.id]) {
                        setTabsElements(tabElements => ({
                          ...tabElements,
                          [tab.id]: tabElement,
                        }))
                      }
                    }}
                    isActiveTab={value.context.activeTab.id === tab.id}
                  >
                    <TabAnchorItem>{tab.title}</TabAnchorItem>
                  </TabTitleItem>
                ))}
              </ListTabs>

              <ActiveTabBorder
                activeTabElement={tabsElements[value.context.activeTab.id]}
              />
            </TabsContainer>

            {children}
          </ReactTabs>
        )}
      </TabsContext.TabConsumer>
    </TabsContext.TabProvider>
  )
}

这里是演示

https://codesandbox.io/s/z3moq8662p

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    首先,您不能在 ref 回调方法中更新状态。其次,您只需将 ref 而不是 innerRef 传递给 TabTitleItem 组件,因为它在内部使用 forwardRef 处理 ref

    const Tabs = ({ activeTab, children }) => {
      const [tabsElements, setTabsElements] = useState([]);
      const tabElements = useRef({});
    
      return (
        <TabsContext.TabProvider activeTab={activeTab}>
          <TabsContext.TabConsumer>
            {value => (
              <ReactTabs>
                <TabsContainer>
                  <ListTabs>
                    {console.log("value", value.context)}
                    {value.context.tabs.map(tab => (
                      <TabTitleItem
                        key={tab.id}
                        onClick={value.context.onClick(tab)}
                        id={tab.id}
                        ref={tabElement => {
                          tabElements.current[tab.id] = tabElement;
                        }}
                        isActiveTab={value.context.activeTab.id === tab.id}
                      >
                        <TabAnchorItem>{tab.title}</TabAnchorItem>
                      </TabTitleItem>
                    ))}
                  </ListTabs>
                  <ActiveTabBorder
                    activeTabElement={tabsElements[value.context.activeTab.id]}
                  />
                </TabsContainer>
    
                {children}
              </ReactTabs>
            )}
          </TabsContext.TabConsumer>
        </TabsContext.TabProvider>
      );
    };
    

    Working demo

    【讨论】:

    • 它不显示边框线,因为 ActiveTabBorder 无法传递选定的活动选项卡元素。它依赖于 tabsElements 状态。当我使用基于类但不在这里时它正在工作
    • 它显示,但不是最初仅在单击选项卡后显示。但是背景颜色必须改变。
    • 你能通过改变 ActiveTabBorder 的背景颜色看到它最初没有显示吗
    • @milan 抱歉耽搁了,我在 SO 上看到了您的另一篇帖子,并为您的上述查询发布了答案
    猜你喜欢
    • 2020-10-23
    • 1970-01-01
    • 2022-01-22
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2020-08-15
    相关资源
    最近更新 更多