面试题答案
一键面试初始化 React Context
- 创建 Context 对象:
在 React 中,使用
createContext
方法来创建一个 Context 对象。这个对象包含了Provider
和Consumer
两个属性。import React from'react'; const MyContext = React.createContext(); export default MyContext;
- 在服务端渲染(SSR)中初始化 Context:
在 SSR 场景下,我们需要在渲染顶层组件时,通过
Provider
来初始化 Context 并传递数据。import React from'react'; import ReactDOMServer from'react-dom/server'; import MyContext from './MyContext'; import App from './App'; const contextData = { someValue: 'initial value for SSR' }; const html = ReactDOMServer.renderToString( <MyContext.Provider value={contextData}> <App /> </MyContext.Provider> );
- 在客户端渲染中初始化 Context:
在客户端,同样需要通过
Provider
来初始化 Context,但数据可能需要从服务端传递过来(例如通过window.__INITIAL_STATE__
这种方式)。import React from'react'; import ReactDOM from'react-dom'; import MyContext from './MyContext'; import App from './App'; const clientContextData = window.__INITIAL_STATE__.contextData; ReactDOM.hydrate( <MyContext.Provider value={clientContextData}> <App /> </MyContext.Provider>, document.getElementById('root') );
在组件树中传递数据
- 使用
Provider
传递数据:Provider
组件接受一个value
属性,这个属性的值会被传递给其所有后代组件中使用Consumer
或useContext
的地方。import React from'react'; import MyContext from './MyContext'; const ParentComponent = () => { const contextValue = { someData: 'data to be passed' }; return ( <MyContext.Provider value={contextValue}> <ChildComponent /> </MyContext.Provider> ); }; const ChildComponent = () => { // 使用 Consumer 或 useContext 获取数据 };
- 使用
Consumer
获取数据(旧方式): 在需要数据的组件中,可以使用Consumer
来订阅 Context 的变化并获取数据。import React from'react'; import MyContext from './MyContext'; const ChildComponent = () => { return ( <MyContext.Consumer> {contextValue => ( <div>{contextValue.someData}</div> )} </MyContext.Consumer> ); };
- 使用
useContext
获取数据(新方式,适用于函数组件): React hooks 提供了useContext
方法,使得获取 Context 数据更加简洁。import React, { useContext } from'react'; import MyContext from './MyContext'; const ChildComponent = () => { const contextValue = useContext(MyContext); return ( <div>{contextValue.someData}</div> ); };
需要注意的是,在 SSR 场景下,要确保服务端和客户端传递的数据一致性,避免出现 hydration 不匹配的问题。例如通过在服务端渲染时将数据序列化并传递到客户端,客户端再反序列化来使用。