为什么上下文组件在 NextJs 页面路由期间重新评估?

2024-03-24

给定一个基本的 NextJs 应用程序,其中包含一个简单的上下文组件和几个页面

// AppContextWrapper.js

export function AppContextWrapper(props) {
  console.log('AppContextWrapper - component function executed');
  const appContextState = useState();
  
  return (
    <AppContext.Provider value={appContextState}>
      {props.children}
    </AppContext.Provider>
  );
}


// _app.js

function MyApp({ Component, pageProps }) {
  return (
    <AppContextWrapper>
      <Layout>
         <Component {...pageProps} />
      </Layout>
    </AppContextWrapper>
  );
}

我注意到从一个页面导航到另一个页面会触发重新执行AppContextWrapper组件功能。

在基本的非 NextJs React 应用程序中,这种情况不会发生。

// index.js

ReactDOM.render(
  <React.StrictMode>
    <AppContextWrapper>
      <App />
    </AppContextWrapper>
  </React.StrictMode>,
  document.getElementById('root')
);

// app.js

function App() {
  return (
    <BrowserRouter>
      <div>
        <nav>
          <ul>
            <li>
              <Link to='/'>Home</Link>
            </li>
            <li>
              <Link to='/other'>Other</Link>
            </li>
          </ul>
        </nav>
        <Switch>
          <Route path='/other'>
            <OtherPage />
          </Route>
          <Route path='/'>
            <HomePage />
          </Route>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

发生这种情况可能是因为在 NextJs 应用程序导航中导致重新分配Component and pageProps in _app.js因此导致重新执行MyApp组件功能。

我有几个与此相关的问题。

重新执行上下文组件函数是否存在潜在问题?

NextJs 应用程序中是否有某个位置可以安装上下文组件来避免重新执行?

最后,我看到了使用的代码useMemo在上下文函数中,就像这样......

// appContextWrapper.js

export function AppContextWrapper(props) {
  console.log('AppContextWrapper component function executed');
  const [appState, setAppState] = useState({});

  const appContextState = useMemo(() => ({ appState, setAppState }), [appState, setAppState]);

  return (
    <AppContext.Provider value={appContextState}>{props.children}</AppContext.Provider>
  );
}

我不明白这种方法是否合理?我的理解是useMemo应用于记忆不会改变的 props 或计算值,以防止子组件的组件函数不必要地重新执行。使用useMemo保存已由 React 通过 useState 管理的值似乎毫无意义且多余。


我认为您所描述的问题是由于不使用浅层路由而导致的。

Nextjs 文档声明了这一点:

浅层路由允许您更改 URL,而无需再次运行数据获取方法,其中包括 getServerSideProps、getStaticProps 和 getInitialProps。

您将通过路由器对象(由 useRouter 或 withRouter 添加)接收更新的路径名和查询,而不会丢失状态。

https://nextjs.org/docs/routing/shallow-routing https://nextjs.org/docs/routing/shallow-routing

您可以通过执行以下操作在 Link 中使用浅层路由:

<Link to='/other' shallow>Other</Link>

并在推喜欢这个

push({pathname: "/other"},undefined,{shallow: true})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么上下文组件在 NextJs 页面路由期间重新评估? 的相关文章

  • 如何找到我的 typescript/react 模块的声明?

    我对前端技术非常 非常 陌生 特别是 React 和 TypeScript 当尝试做一件简单的事情 即使用反应组件时 我的问题出现了https github com ckeditor ckeditor5 https github com c
  • 在本地主机中保存更改后,React 组件不会在浏览器中重新加载

    我使用 Create React App 创建了一个新的 React 项目 在旧项目中 每当我在组件中进行更改并保存组件时 它都会反映在浏览器中 但在新项目中 当我保存代码中的更改时 浏览器不会重新加载 也不会反映更改 所以我停止了正在运行
  • 通过内联样式动态设置背景 Div 图像时不显示 | Next.Js

    我试图通过使用地图和外部 js 文件将图像存储为对象来从组件渲染图像 然后通过它们设置循环 将其设置为创建的每个 div 的不同背景图像 如果有意义的话 我将提供代码来更清楚地说明我想要完成的任务 在地图过程中 我试图定位对象方法 但我相信
  • 如何在 React 中正确捕获 Materialize-CSS datepicker 值?

    我希望创建一个带有日期选择器 https materializecss com pickers html在我的 React 组件中物化CSS https materializecss com 该表单捕获的字段不多 而且结构相当简单 返回的表
  • 如何在提交值后重置 antd datepicker?

    在这里 我提供了在codesandbox上工作的示例 提交表单后如何重置日期选择器值 state setFieldValue onChange setFieldValue gt this setState setFieldValue nul
  • 更改 Office UI Fabric React 组件的颜色/主题?

    我正在尝试使用Office UI Fabric React 组件 https dev office com fabric components在我的网络应用程序中 有没有办法改变组件的颜色或主题 例如 我尝试了这样的事情 ReactDOM
  • 如何将 React Native 按钮放置在屏幕底部以在多个 ios 设备上工作

    我还年轻 在网上搜索可以帮助我解决这个问题的教程 但没有找到任何东西 我知道如何将屏幕上的按钮从 A 点移动到 B 点 问题是我似乎无法将其固定在底部以在我的 ios 模拟器的不同外形尺寸上工作 到目前为止 我已经尝试过 marginTop
  • react-google-maps/api 避免在某些状态更改后重新渲染地图

    我遇到了问题 我的 GoogleMaps 实例会刷新并以某些方式自我居中onClick设置状态的函数 并且将发生整个组件渲染周期 经过一番谷歌搜索后 有人建议将组件实例化分开并重新使用 现在的问题是我有一些逻辑来在内部显示标记
  • React 导航抽屉中的 React Native 显示模式

    我有一个应用程序 我希望当用户单击某些导航路线时在当前页面上显示模式 而不是导航到完全不同的页面 我现有的代码是 const DrawerNavigator gt return
  • 将字体导入 React 应用程序

    我正在尝试在我的应用程序中使用 Roboto 字体 但遇到了困难 I did npm install save typeface roboto并添加了import typeface roboto 到我的 React 组件 但仍然无法改变我的
  • React 包的 CDN 链接以及在使用 React 时如何使用 CDN 中的脚本导入它

    我尝试在没有 NPM 和其他工具的情况下使用 React 而是通过添加 CDN 链接来使用它 但是如何导入依赖包 例如useState hook 如果它是通过另一个脚本标签添加的 那么它的 CDN 链接是什么 下面是我的代码
  • 如何使用 Typescript 从 mui 扩展调色板

    我正在尝试扩展 mui 提供的调色板 覆盖主色 次要颜色等效果很好 但如果我想在之后创建一组自定义颜色 我不知道如何使其工作 有很多没有打字稿的例子 但是当这个人进入游戏时 事情就变得更加棘手 假设我有这个 主题 tsx palette p
  • React router v4 嵌套路由相对路径

    我有一个带有 React Router v4 的组件到另一个组件 我想在第二个组件中添加另一个路由 这是主要路线 const Dashboard gt return div div
  • 如何过滤javascript对象数组

    我有两个数组 我正在使用 PubSidebar 过滤基于 groupKey 的内容 let groupKey oaDeal Journals Deposit This array of object will be filtering wi
  • 类型错误:无法读取未定义的属性“存在”

    我正在尝试为 jsx 文件编写一个测试用例 在此我能够传递 proptypes 但不是我正确传递 proptypes 的地方 当我运行测试用例时出现错误 下面提供我的错误 测试用例和代码 类型错误 无法读取未定义的属性 存在 不知道如何让它
  • 对大数据块进行反应非阻塞渲染

    最近我开始学习反应并想知道是否有某种模式可以用于大数据的非阻塞 UI 线程渲染 比方说 我们采取这个例子 https www mendix com tech blog making react reactive pursuit high p
  • 如何在 NextJS 应用程序中处理公共和私有路由?

    我正在开发一个具有公共和管理路由的应用程序 在过去的 CRA 应用程序中 我们使用了自定义路由元素 但我们在 nextjs 中没有 Thins 我们有很多公共页面 我们有 20 个私人页面 路线 在 nextjs 中处理受保护的经过身份验证
  • React Native 将样式设置为 State

    我想用backgroundColor of style1作为一种状态 并在函数中改变它change 我怎样才能访问style1 我的观点是调用该函数change从另一个函数 使按钮将其颜色更改为黄色 然后在一段时间后再次将其颜色更改为蓝色
  • 从React Redux中的package.json获取版本号(create-react-app)

    OP 编辑 如果其他人遇到此问题 该应用程序是使用创建的创建反应应用程序 https github com facebookincubator create react app 这限制导入到 src 文件夹内 但是如果你将react scr
  • React + 路由器 + Google 标签管理器

    我花了一些时间在 Quickcypher com 上开发 MVP 我想开始进行一些分析 它对于跟踪总访问量非常有用 但是当我尝试跟踪使用 React Router 的网站上的不同 URL 时 情况却出问题了 我的方法是这样的 设置一个在某些

随机推荐