【问题标题】:Context API loses data on switching router links上下文 API 在切换路由器链接时丢失数据
【发布时间】:2021-09-25 04:24:11
【问题描述】:

https://codesandbox.io/s/fast-glitter-3mpwx

嗨, 在上面的代码框中,有两个路由器链接设计和构建,每个链接都包含一个计数器组件,其中 DesignContextProvider 用于设计,BuildContextProvider 用于构建

计数器变量在BuildContextDesignContext 中都可用,所以当我从BuildContext 增加计数器并切换到设计路线BuildContext 丢失数据,重置为0,反之亦然DesignContext ,感觉 Context 正在重新渲染并应用初始状态

我想要实现的是,即使在切换HashRouter 链接之后,也要在两个上下文上维护数据

构建上下文:

import { createContext, Component } from "react";

export class BuildContextProvider extends Component {
    
    state = {
        counter: 0,
    };

    updateCounter = () => {
        this.setState({
            counter: this.state.counter + 1,
        })
    }
    
    render() {
        return(
            <BuildContext.Provider
                value={{ ...this.state, updateCounter: this.updateCounter }}
            >
                {this.props.children}
            </BuildContext.Provider>
        )
    }
}

export const BuildContext = createContext();

设计上下文:

import { createContext, Component } from "react";

export class DesignContextProvider extends Component {
    
    state = {
        counter: 0,
    };

    updateCounter = () => {
        this.setState({
            counter: this.state.counter + 1,
        })
    }
    
    render() {
        return(
            <DesignContext.Provider
                value={{ ...this.state, updateCounter: this.updateCounter }}
            >
                {this.props.children}
            </DesignContext.Provider>
        )
    }
}

export const DesignContext = createContext();

App.js

<Switch>
        <Route path="/build">
          <BuildContextProvider>
            <Build></Build>
          </BuildContextProvider>
        </Route>

        <Route path="/design">
          <DesignContextProvider>
            <Design></Design>
          </DesignContextProvider>
        </Route>
      </Switch>

构建和设计组件:

const Build = () => {
    const { updateCounter, counter } = useContext(BuildContext);
    return(
        <div>
            <button onClick={updateCounter}>+</button>
            <span>{counter}</span>
        </div>
    )
}

const Design = () => {
    const { updateCounter, counter } = useContext(DesignContext);
    return(
        <div>
            <button onClick={updateCounter}>+</button>
            <span>{counter}</span>
        </div>
    )
}

【问题讨论】:

    标签: reactjs react-router-dom react-context


    【解决方案1】:

    您可以将提供程序放在路由之外,这样提供程序中的状态就不会重置

    <DesignContextProvider>
        <BuildContextProvider>
            <Switch>
    
            <Route path="/build">
                <Build/>
            </Route>
    
            <Route path="/design">
                <Design/>
            </Route>
          </Switch>
        </BuildContextProvider>
      </DesignContextProvider>
    

    【讨论】:

    • 但是在这种情况下,当用户只想访问构建页面时,我会为所有提供者获取数据,目前这里只有 2 个路由器链接,但在我的主项目文件中有 5 个链接,所以 5单独的提供者,包括将拥有大量数据的报告提供者..
    • 如果你想保持状态,你需要在路由组件周围放置提供者。您可以在提供程序中有一个函数 fetchData,并在构建和设计中使用 useEffect 来调用 fetchData。
    • David 我们可以做到这一点,但问题是当用户只想访问其中一个选项卡时,我会调用其他 4 个选项卡的数据,所以我会收集其他 4 个选项卡的数据,我认为这是不合适的,因为我将对所有 5 个选项卡使用代码拆分,我在这里试图实现的是与所有其他 4 个选项卡拆分的数据,当用户只访问一次时,应该加载数据
    • Prem,也许这是您的选择。如果您围绕它创建一个 StateProvider,您只需保留状态并设置状态。在构建和设计中,您可以拥有所有逻辑/功能。所以 StateProvider 保持很小并且只有状态,其他提供程序可以变大但仅在页面加载时加载。 codesandbox.io/s/clever-kowalevski-nsqnq?file=/src/Context/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    • 2012-10-20
    • 2018-03-05
    相关资源
    最近更新 更多