我正在使用通过上下文传递的函数.
ChildComponent.contextType = SomeContext;
Run Code Online (Sandbox Code Playgroud)
现在我用this.context.someFunction();.这有效.
如果我需要来自两个不同父组件的函数,我该怎么做?
cor*_*ard 23
你仍然可以使用16.3 Context API的函数作为子消费者节点,这是React文档建议做的:
// Theme context, default to light theme
const ThemeContext = React.createContext('light');
// Signed-in user context
const UserContext = React.createContext({
name: 'Guest',
});
class App extends React.Component {
render() {
const {signedInUser, theme} = this.props;
// App component that provides initial context values
return (
<ThemeContext.Provider value={theme}>
<UserContext.Provider value={signedInUser}>
<Layout />
</UserContext.Provider>
</ThemeContext.Provider>
);
}
}
function Layout() {
return (
<div>
<Sidebar />
<Content />
</div>
);
}
// A component may consume multiple contexts
function Content() {
return (
<ThemeContext.Consumer>
{theme => (
<UserContext.Consumer>
{user => (
<ProfilePage user={user} theme={theme} />
)}
</UserContext.Consumer>
)}
</ThemeContext.Consumer>
);
}
Run Code Online (Sandbox Code Playgroud)
要在组件的上下文中使用函数,通常将组件包装在HOC中,以便将上下文作为props传递:
export const withThemeContext = Component => (
props => (
<ThemeContext.Consumer>
{context => <Component themeContext={context} {...props} />}
</ThemeContext.Consumer>
)
)
const YourComponent = ({ themeContext, ...props }) => {
themeContext.someFunction()
return (<div>Hi Mom!</div>)
}
export default withThemeContext(YourComponent)
Run Code Online (Sandbox Code Playgroud)
Dim*_*rov 13
另一种解决方案是创建一个单独的上下文来提供其他上下文:
import React, { createContext, memo, useContext } from "react";
import isEqual from "react-fast-compare";
export const MultiContext = createContext(null);
MultiContext.displayName = "MultiContext";
export const MultiContextProvider = memo(
function({ map, children }) {
const contextMap = {};
for (const i in map) {
contextMap[i] = useContext(map[i]);
}
return (
<MultiContext.Provider value={contextMap}>
{children}
</MultiContext.Provider>
);
},
(prevProps, nextProps) => isEqual(prevProps.children, nextProps.children)
);
MultiContextProvider.displayName = "MultiContextProvider";
Run Code Online (Sandbox Code Playgroud)
用法示例:
class DemoConsumer extends React.Component {
static contextType = MultiContext;
render() {
return JSON.stringify({
someValue: this.context.SomeContext.someValue,
otherValue: this.context.OtherContext.otherValue,
});
}
}
function App() {
return (
<MultiContextProvider map={{ SomeContext, OtherContext }}>
<MultiContextDemoClassConsumer />
</MultiContextProvider>
);
}
Run Code Online (Sandbox Code Playgroud)
演示:
import React, { createContext, memo, useContext } from "react";
import isEqual from "react-fast-compare";
export const MultiContext = createContext(null);
MultiContext.displayName = "MultiContext";
export const MultiContextProvider = memo(
function({ map, children }) {
const contextMap = {};
for (const i in map) {
contextMap[i] = useContext(map[i]);
}
return (
<MultiContext.Provider value={contextMap}>
{children}
</MultiContext.Provider>
);
},
(prevProps, nextProps) => isEqual(prevProps.children, nextProps.children)
);
MultiContextProvider.displayName = "MultiContextProvider";
Run Code Online (Sandbox Code Playgroud)
class DemoConsumer extends React.Component {
static contextType = MultiContext;
render() {
return JSON.stringify({
someValue: this.context.SomeContext.someValue,
otherValue: this.context.OtherContext.otherValue,
});
}
}
function App() {
return (
<MultiContextProvider map={{ SomeContext, OtherContext }}>
<MultiContextDemoClassConsumer />
</MultiContextProvider>
);
}
Run Code Online (Sandbox Code Playgroud)
您还可以将所有上下文简单地合并为一个上下文:
const AppContext = React.createContext({
user: { name: 'Guest' },
theme: 'light',
})
ChildComponent.contextType = AppContext;
Run Code Online (Sandbox Code Playgroud)
做完了 如果您在应用程序的某些部分具有不同的上下文(例如,不同的主题或用户),则只需合并新值。