Next.js类组件跨页面共享API返回JSON数据方案咨询
在Next.js类组件中跨无父组件页面共享API数据的实现方案
下面是几种适合类组件场景的可行方案,可根据数据规模和业务需求选择:
1. React Context + App组件全局共享
Next.js的_app.js是所有页面的根容器,可借助它实现全局状态共享:
- 第一步:创建Context文件
// context/SharedDataContext.js import React from 'react'; const SharedDataContext = React.createContext({ data: null, setData: () => {} }); export default SharedDataContext;
- 第二步:在
_app.js中提供Context
// pages/_app.js import React from 'react'; import SharedDataContext from '../context/SharedDataContext'; class MyApp extends React.Component { state = { sharedData: null, setSharedData: (data) => this.setState({ sharedData: data }) }; render() { const { Component, pageProps } = this.props; return ( <SharedDataContext.Provider value={this.state}> <Component {...pageProps} /> </SharedDataContext.Provider> ); } } export default MyApp;
- 第三步:在API请求组件中更新Context
// 你的API请求组件 import React from 'react'; import SharedDataContext from '../context/SharedDataContext'; class ApiFetcher extends React.Component { static contextType = SharedDataContext; componentDidMount() { // 模拟API请求 fetch('/your-api-endpoint') .then(res => res.json()) .then(data => { this.context.setSharedData(data); }); } render() { return <div>数据已获取</div>; } } export default ApiFetcher;
- 第四步:在三个页面组件中读取数据
// 任意页面组件 import React from 'react'; import SharedDataContext from '../context/SharedDataContext'; class PageA extends React.Component { static contextType = SharedDataContext; render() { const { sharedData } = this.context; return ( <div> {sharedData ? <pre>{JSON.stringify(sharedData, null, 2)}</pre> : '加载中...'} </div> ); } } export default PageA;
2. Redux全局状态管理
适合数据结构复杂、多组件频繁交互的场景:
- 配置Redux store(创建reducer、store)
// store/reducers/sharedDataReducer.js const initialState = { data: null }; export default function sharedDataReducer(state = initialState, action) { switch (action.type) { case 'SET_SHARED_DATA': return { ...state, data: action.payload }; default: return state; } } // store/index.js import { createStore, combineReducers } from 'redux'; import sharedDataReducer from './reducers/sharedDataReducer'; const rootReducer = combineReducers({ sharedData: sharedDataReducer }); export const store = createStore(rootReducer);
- 在
_app.js中注入store
// pages/_app.js import React from 'react'; import { Provider } from 'react-redux'; import { store } from '../store'; class MyApp extends React.Component { render() { const { Component, pageProps } = this.props; return ( <Provider store={store}> <Component {...pageProps} /> </Provider> ); } } export default MyApp;
- 在API请求组件中dispatch更新数据
import React from 'react'; import { connect } from 'react-redux'; class ApiFetcher extends React.Component { componentDidMount() { fetch('/your-api-endpoint') .then(res => res.json()) .then(data => { this.props.setSharedData(data); }); } render() { return <div>数据已获取</div>; } } const mapDispatchToProps = (dispatch) => ({ setSharedData: (data) => dispatch({ type: 'SET_SHARED_DATA', payload: data }) }); export default connect(null, mapDispatchToProps)(ApiFetcher);
- 在页面组件中读取数据
import React from 'react'; import { connect } from 'react-redux'; class PageA extends React.Component { render() { const { sharedData } = this.props; return ( <div> {sharedData ? <pre>{JSON.stringify(sharedData, null, 2)}</pre> : '加载中...'} </div> ); } } const mapStateToProps = (state) => ({ sharedData: state.sharedData.data }); export default connect(mapStateToProps)(PageA);
3. 浏览器本地存储(localStorage/sessionStorage)
适合数据不敏感、无需实时同步多标签页的场景:
- 在API请求组件中存储数据
import React from 'react'; class ApiFetcher extends React.Component { componentDidMount() { fetch('/your-api-endpoint') .then(res => res.json()) .then(data => { // 存入localStorage可持久化保存;用sessionStorage则会话结束后清除 localStorage.setItem('sharedApiData', JSON.stringify(data)); }); } render() { return <div>数据已获取</div>; } } export default ApiFetcher;
- 在页面组件中读取数据
import React from 'react'; class PageA extends React.Component { state = { sharedData: null }; componentDidMount() { const storedData = localStorage.getItem('sharedApiData'); if (storedData) { this.setState({ sharedData: JSON.parse(storedData) }); } } render() { const { sharedData } = this.state; return ( <div> {sharedData ? <pre>{JSON.stringify(sharedData, null, 2)}</pre> : '加载中...'} </div> ); } } export default PageA;
4. URL参数传递(仅适合小体积数据)
如果API返回的数据体积很小,可通过URL query参数传递:
- 在跳转时携带数据
import React from 'react'; import Router from 'next/router'; class ApiFetcher extends React.Component { componentDidMount() { fetch('/your-api-endpoint') .then(res => res.json()) .then(data => { // 序列化数据后作为query参数 Router.push({ pathname: '/page-a', query: { data: JSON.stringify(data) } }); }); } render() { return <div>跳转中...</div>; } } export default ApiFetcher;
- 在目标页面中解析数据
import React from 'react'; class PageA extends React.Component { static async getInitialProps({ query }) { let sharedData = null; if (query.data) { sharedData = JSON.parse(query.data); } return { sharedData }; } render() { const { sharedData } = this.props; return ( <div> {sharedData ? <pre>{JSON.stringify(sharedData, null, 2)}</pre> : '无数据'} </div> ); } } export default PageA;
内容的提问来源于stack exchange,提问作者Shreya
相关产品推荐
相关产品推荐

