Javascript HOC-功能组件
我已经在我的react应用程序中创建了一个HOC,它工作正常。然而,我想知道是否有一种方法可以创建一个HOC作为功能组件(有状态还是没有状态)???因为给定的示例是基于类的组件 试图在网上找到相同的内容,但什么也找不到。不确定这是否可能??还是做正确的事Javascript HOC-功能组件,javascript,reactjs,components,higher-order-components,Javascript,Reactjs,Components,Higher Order Components,我已经在我的react应用程序中创建了一个HOC,它工作正常。然而,我想知道是否有一种方法可以创建一个HOC作为功能组件(有状态还是没有状态)???因为给定的示例是基于类的组件 试图在网上找到相同的内容,但什么也找不到。不确定这是否可能??还是做正确的事 任何潜在客户都会受到欢迎:)当然,您可以创建一个功能性无状态组件,该组件接受组件作为输入,并返回其他组件作为输出,例如 您可以创建一个PrivateRoute组件,该组件接受一个组件作为prop值,并根据用户是否经过身份验证返回一些其他组件 如
任何潜在客户都会受到欢迎:)当然,您可以创建一个功能性无状态组件,该组件接受组件作为输入,并返回其他组件作为输出,例如
将用户重定向到登录页面,否则返回作为道具传递的组件,并将其他道具发送到该组件
const-App=()=>{
返回(
);
}
导出默认应用程序;
PrivateRoute.jsx
import React,{useContext,useffect}来自“React”;
从“react router dom”导入{Route,Redirect}
从“../../context/auth/AuthContext”导入AuthContext
const privaterout=({component:component,…rest})=>{
const authContext=useContext(authContext)
常量{loadUser,isAuthenticated}=authContext
useffect(()=>{
loadUser()
//eslint禁用下一行
}, [])
如果(isAuthenticated==null){
返回
}
返回(
!我被认证了(
) : (
)
}
/>
);
};
导出默认私有路由;
高阶组件不必是类组件,它们的目的是根据某些逻辑将组件作为输入,并将组件作为输出返回。当然,您可以在react中创建功能性的HOC,也可以为其创建任何其他文件夹,如“Utils”。例如,它是Utils文件夹中的my amountUtil.js文件: 导出常量getFormattedAmount=(金额?:金额)=>( 金额&
${amount.formattedAmount}${amount.currency}
); 我同意,严格地说,这个例子不是一个真正的例子。HOC的区别在于它返回一个组件,而接受答案中的privaterote
组件本身就是一个组件。因此,虽然它很好地完成了它开始要做的事情,但我不认为这是一个很好的HOC示例
在功能组件世界中,最基本的HOC如下所示:
const withNothing = Component => ({ ...props }) => (
<Component {...props} />
);
使用这种方法的一种方法是,如果您想使用特别(没有双关语的lol)上下文提供程序
假设我的应用程序有多个用户可以登录的点。我不想在所有这些点上复制登录逻辑(API调用和成功/错误消息),所以我想要一个可重用的
组件。然而,在我的例子中,所有这些登录点在视觉上都有很大的不同,所以可重用组件不是一个选项。我需要的是一个可重用的
组件,它将为其子组件提供所有必要的功能—API调用和成功/错误消息。有一种方法可以做到这一点:
// This context will only hold the `login` method.
// Calling this method will invoke all the required logic.
const LoginContext = React.createContext();
LoginContext.displayName = "Login";
// This "HOC" (not a true HOC yet) should take care of
// all the reusable logic - API calls and messages.
// This will allow me to pass different layouts as children.
const WithLogin = ({ children }) => {
const [popup, setPopup] = useState(null);
const doLogin = useCallback(
(email, password) =>
callLoginAPI(email, password).then(
() => {
setPopup({
message: "Success"
});
},
() => {
setPopup({
error: true,
message: "Failure"
});
}
),
[setPopup]
);
return (
<LoginContext.Provider value={doLogin}>
{children}
{popup ? (
<Modal
error={popup.error}
message={popup.message}
onClose={() => setPopup(null)}
/>
) : null}
</LoginContext.Provider>
);
};
// This is my main component. It is very neat and simple
// because all the technical bits are inside WithLogin.
const MyComponent = () => {
const login = useContext(LoginContext);
const doLogin = useCallback(() => {
login("a@b.c", "password");
}, [login]);
return (
<WithLogin>
<button type="button" onClick={doLogin}>
Login!
</button>
</WithLogin>
);
};
然后:
const MyComponent = () => {
const login = useContext(LoginContext);
const doLogin = useCallback(() => {
login("a@b.c", "password");
}, [login]);
return (
<button type="button" onClick={doLogin}>
Login!
</button>
);
};
const MyComponentWithLogin = withLogin(MyComponent);
constmycomponent=()=>{
const login=useContext(LoginContext);
const doLogin=useCallback(()=>{
登录(“a@b.c“,”密码“);
},[登录];
返回(
登录!
);
};
常量MyComponentWithLogin=withLogin(MyComponent);
砰MyComponentWithLogin
现在将按预期工作
这可能不是处理这种特殊情况的最佳方式,但我有点喜欢
是的,它实际上只是一个额外的函数调用,仅此而已!根据官方指南:
HOC本身不是React API的一部分。它们是从React的组成性质中产生的一种模式
下面是一个将HOC与功能组件结合使用的过于简化的示例 要“包装”的功能组件:
import React from 'react'
import withClasses from '../withClasses'
const ToBeWrappedByHOC = () => {
return (
<div>
<p>I'm wrapped by a higher order component</p>
</div>
)
}
export default withClasses(ToBeWrappedByHOC, "myClassName");
import React from 'react'
const withClasses = (WrappedComponent, classes) => {
return (props) => (
<div className={classes}>
<WrappedComponent {...props} />
</div>
);
};
export default withClasses;
从“React”导入React
从“../withClasses”导入withClasses
常数ToBeWrappedByHOC=()=>{
返回(
我被一个高阶组件包住了
)
}
导出带有类的默认值(ToBeWrappedByHOC,“myClassName”);
高阶组件:
import React from 'react'
import withClasses from '../withClasses'
const ToBeWrappedByHOC = () => {
return (
<div>
<p>I'm wrapped by a higher order component</p>
</div>
)
}
export default withClasses(ToBeWrappedByHOC, "myClassName");
import React from 'react'
const withClasses = (WrappedComponent, classes) => {
return (props) => (
<div className={classes}>
<WrappedComponent {...props} />
</div>
);
};
export default withClasses;
从“React”导入React
常量withClasses=(WrappedComponent,classes)=>{
返回(道具)=>(
);
};
导出默认类;
该组件可以在其他组件中使用,如下所示
<ToBeWrappedByHOC/>
它看起来更像一个HOC组件,更像一个包装器组件。HOC返回FC not REACTION元素。如果我想在此处设置管理路由,该怎么办?我该怎么做?那么你的应用程序是否支持多重授权,例如用户和管理员?如果是这样,您可以创建一个名为的组件,并检查person是否为admin(而不是此处的isAuthenticated),这样只有拥有属性admin的人(从身份验证的响应中检查)才能访问该组件。请参阅下面的答案并修改您的答案或删除。感谢您试图提供帮助,但回答有误导性。私有路由并没有返回一个组件,这听起来很奇怪。在这种情况下,组件是道具的功能,而不是某些JSX的结果。