Reactjs 对多种情况作出反应
我正在使用通过上下文传递的函数Reactjs 对多种情况作出反应,reactjs,Reactjs,我正在使用通过上下文传递的函数 ChildComponent.contextType = SomeContext; 现在我使用this.context.someFunction()。这很有效 如果我需要来自两个不同父组件的函数,如何执行此操作?您仍然可以在16.3上下文API中使用函数作为子使用者节点,这就是: 或者,如果您大量使用这些上下文,您甚至可以制作一个自定义挂钩来进一步简化: const useTheme = () => useContext(ThemeContext) con
ChildComponent.contextType = SomeContext;
现在我使用this.context.someFunction()代码>。这很有效
如果我需要来自两个不同父组件的函数,如何执行此操作?您仍然可以在16.3上下文API中使用函数作为子使用者节点,这就是:
或者,如果您大量使用这些上下文,您甚至可以制作一个自定义挂钩来进一步简化:
const useTheme = () => useContext(ThemeContext)
const useUser = () => useContext(UserContext)
const YourComponent = props => {
const theme = useTheme()
const user = useUser()
}
您也可以简单地将所有上下文合并为一个上下文:
const AppContext = React.createContext({
user: { name: 'Guest' },
theme: 'light',
})
ChildComponent.contextType = AppContext;
完成了。如果应用程序的某些部分有不同的上下文(如不同的主题或用户),则只需合并新值。另一种解决方案是创建一个单独的上下文,提供其他上下文:
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";
import React,{createContext,memo,useContext}来自“React”;
从“快速反应比较”中导入isEqual;
export const MultiContext=createContext(null);
MultiContext.displayName=“MultiContext”;
导出常量MultiContextProvider=memo(
函数({map,children}){
const contextMap={};
用于(地图中的常数i){
contextMap[i]=useContext(map[i]);
}
返回(
{儿童}
);
},
(prevProps,nextProps)=>isEqual(prevProps.children,nextProps.children)
);
MultiContextProvider.displayName=“MultiContextProvider”;
用法示例:
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>
);
}
类DemoConsumer扩展React.Component{
静态上下文类型=多上下文;
render(){
返回JSON.stringify({
someValue:this.context.SomeContext.someValue,
otherValue:this.context.OtherContext.otherValue,
});
}
}
函数App(){
返回(
);
}
演示:
const{
createContext,
备忘录,
使用上下文,
useState,
使用效果,
}=反应;
const MultiContext=createContext(null);
MultiContext.displayName=“MultiContext”;
const multicntextprovider=memo(
函数({map,children}){
console.log(“呈现提供程序”);
const contextMap={};
用于(地图中的常数i){
contextMap[i]=useContext(map[i]);
}
返回(
{儿童}
);
},
(prevProps,nextProps)=>isEqual(prevProps.children,nextProps.children)
);
MultiContextProvider.displayName=“MultiContextProvider”;
const initialMinutes=新日期().getMinutes();
const MinutesContext=createContext(initialMinutes);
MinutesContext.displayName=“MinutesContext”;
const IncrementContext=createContext(0);
IncrementContext.displayName=“IncrementContext”;
类MultiContextDemoClassConsumer扩展React.Component{
静态上下文类型=多上下文;
render(){
返回JSON.stringify(this.context);
}
}
常量multiContextMap={minuteContext,IncrementContext};
函数App(){
const forceUpdate=useForceUpdate();
const[minutes,setMinutes]=使用状态(initialMinutes);
useffect(()=>{
const timeoutId=setInterval(()=>{
//console.log('set minutes')
setMinutes(新日期().getMinutes());
}, 1000);
return()=>{
清除间隔(超时ID);
};
},[setMinutes]);
const[increment,setIncrement]=useState(0);
console.log(“渲染应用程序”);
返回(
setIncrement(i=>i+1)}>Increment
部队更新
);
}
render(,document.getElementById(“根”))代码>
导入从'https://dev.jspm.io/react@16';
从'https://dev.jspm.io/react-dom@16';
从导入useForceUpdate'https://dev.jspm.io/use-force-update@1.0.7';
从'https://dev.jspm.io/react-fast-compare@3.0.1';
window.React=反应;
window.ReactDOM=ReactDOM;
window.useForceUpdate=useForceUpdate.default;
window.isEqual=isEqual;
上下文为我提供了在类中使用的函数,而不是要呈现的数据。@ATOzTOA这在多个上下文提供程序中的效果与正常情况相同,但我用一个简单的示例更新了我的答案。当您的组件
是一个类时,themeContext
变成This.props.themeContext
,对吗?如果我真的需要将这些上下文彼此分离,我也会使用这种方法。我特别喜欢使用和secondext
HOC:)重新考虑您的解决方案。当某些嵌套对象中的上下文值更改时,它会进行额外的重新渲染,不是吗?用户和主题都可以有嵌套对象,并且在更改对象后(即使不需要),它会导致到处重新渲染,除非我弄错了。请纠正我的错误wrong@sunpietro如果上下文的值更改,则任何使用上下文的组件都将重新渲染,是。这就是为什么在树的顶部有一个不经常变化的上下文,而在使用它的地方有一个变化很大的上下文是有意义的。你的解决方案很好,但为了避免渲染过度,我们可以使用useReducer钩子创建一个上下文。@HoussemBadri也许你可以发布一个答案来说明你的建议?
const AppContext = React.createContext({
user: { name: 'Guest' },
theme: 'light',
})
ChildComponent.contextType = AppContext;
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";
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>
);
}