简体   繁体   English

反应上下文“更新”无法正常工作

[英]React context “update” not working properly

I'm making custom tab component and I have issue on closing tab.我正在制作自定义选项卡组件,但在关闭选项卡时遇到问题。 Switching tab is working ok but when I close last tab I want to set active previouse tab and this is not working.切换选项卡工作正常,但是当我关闭最后一个选项卡时,我想设置活动的上一个选项卡,这不起作用。

setTabs (context update) is updating array "data" in object but not "activeTab". setTabs(上下文更新)正在更新 object 中的数组“数据”,而不是“activeTab”。

I'm using react Context to store list of tabs and active tab.我正在使用 react Context 来存储选项卡列表和活动选项卡。 Switching tabs is working correctly, opening new tab also works fine.切换选项卡工作正常,打开新选项卡也工作正常。

TabsContext选项卡上下文

import React, { useReducer, useEffect } from "react";

const initialState = {
  data: [
    {
      name: "Start",
      component: "StartTab",
      cantClose: true,
      params: null
    }
  ],
  activeTab: 0
};

const localState = JSON.parse(localStorage.getItem("tabs"));
const TabsContext = React.createContext();

let reducer = (tabs, newTabs) => {
  if (newTabs === null) {
    localStorage.removeItem("tabs");
    return initialState;
  }
  return { ...tabs, ...newTabs };
};

function TabsProvider(props) {
  const [tabs, setTabs] = useReducer(reducer, localState || initialState);

  useEffect(() => {
    localStorage.setItem("tabs", JSON.stringify(tabs));
  }, [tabs]);

  return (
    <TabsContext.Provider value={{ tabs, setTabs }}>
      {props.children}
    </TabsContext.Provider>
  );
}

export { TabsContext, TabsProvider };

MainTabs Component: MainTabs 组件:

import React, { Component, useContext } from "react";
import { TabsContext } from "../../providers/TabsProvider";
import StartTab from "./tab.start";
...

class TabComponent extends Component {
    components = {
        StartTab: StartTab,
        ...
    };

    render() {
        const TagName = this.components[this.props.tag];
        return <TagName />
    }
}

const TabsMain = () => {
    const { tabs, setTabs } = useContext(TabsContext);

    const closeTab = (index) => {
        tabs.data.splice(index, 1);

        if (tabs.activeTab == tabs.data.length ) {
            tabs.activeTab--;
        }

        setTabs({ data: tabs.data, activeTab: tabs.activeTab });
    };

    const tabsNavigation = tabs.data.map((tab, index) =>
        <li key={index}>
            <button
                onClick={() => {
                    setTabs({ data: tabs.data, activeTab: index });
                }}
                className={`${tabs.activeTab == index ? 'active' : ''}`}
            >
                {tab.name}
                <div onClick={() => {
                    closeTab(index);
                }} className={`close_button ${!tab.cantClose ? 'show' : 'hide'}`}>X</div>
            </button>
        </li>
    );

    const tabsPanels = tabs.data.map((tab, index) =>
        <div key={index} className={`panel ${tabs.activeTab == index ? 'active' : ''}`}>
            <TabComponent tag={tab.component} />
        </div>
    );

    return (
        <div className="tabs">
            <ul className="tabs__navigation">
                {tabsNavigation}
            </ul>
            <div className="tabs__content">
                {tabsPanels}
            </div>
        </div>
    );
};

export default TabsMain;

Navigation Component导航组件

import React, { Component, useContext } from "react";
import { TabsContext } from "../../providers/TabsProvider";

const Navigation = () => {
    const { tabs, setTabs } = useContext(TabsContext);

    const openTab = (newTab) => {
        tabs.data.push(newTab);
        setTabs(tabs);
    };

    return (
        <ul className="navigation">
            <li>
               <button onClick={() => { openTab({ name: "Start", component: "StartTab" }); }}>
                  Start
               </button>
            </li>
        </ul>
    );
};

export default Navigation;

I found the solution.我找到了解决方案。 First of all I have double click action: 1) on click on tab - selectTab, 2) on "X" on same button, when i clicked X then selectTab and closeTab are fired (setTabs was fired also two times)首先我有双击动作:1)点击选项卡 - selectTab,2)在同一个按钮上的“X”上,当我点击X然后selectTab和closeTab被触发(setTabs也被触发了两次)

The solution Was to extract "X" from button - from this:解决方案是从按钮中提取“X” - 从此:

            <button
                onClick={() => {
                    setTabs({ data: tabs.data, activeTab: index });
                }}
                className={`${tabs.activeTab == index ? 'active' : ''}`}
            >
                {tab.name}
            <div onClick={() => {
                closeTab(index);
            }} className={`close_button ${!tab.cantClose ? 'show' : 'hide'}`}>X</div>
            </button>

to this:对此:

            <button
                onClick={() => {
                    setTabs({ data: tabs.data, activeTab: index });
                }}
                className={`${tabs.activeTab == index ? 'active' : ''}`}
            >
                {tab.name}
            </button>
            <div onClick={() => {
                closeTab(index);
            }} className={`close_button ${!tab.cantClose ? 'show' : 'hide'}`}>X</div>

and change closeTab function to this:并将 closeTab function 更改为:

    const closeTab = (index) => {
        tabs.data.splice(index, 1);
        setTabs({ data: tabs.data, activeTab: index-1 });
    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM