我有一个简单的HOC,它在包装的组件中注入了一个反应上下文作为道具。
function withTranslate(WrappedComponent) {
//we forward the ref so it can be used by other
return React.forwardRef((props, ref) => (
<TranslatorContext.Consumer>
{context => (<WrappedComponent {...props} translate={context} ref={ref} />)}
</TranslatorContext.Consumer>)
)
}
现在,我想要一个使用相同上下文的辅助HOC,但是使用该上下文更改一些预定义的props。我成功完成以下代码:
export function withTranslatedProps(WrappedComponent,propsToBeTransLated) {
//propsToBetranslated is array with all props which will be given via keys
const translateProps=(translate,props)=>{
const ownProps=Object.assign({},props)
propsToBeTransLated.forEach(p=>{
if(ownProps.hasOwnProperty(p)){
ownProps[p]=translate(ownProps[p])
}
})
return ownProps
}
return React.forwardRef((props, ref) => {
console.log("render contextconsumer")
return (
<TranslatorContext.Consumer>
{context => (
<WrappedComponent {...translateProps(context,props)} ref={ref} />
)}
</TranslatorContext.Consumer>)
})
}
但是我几乎完全使用与withTranslate相同的HOC。有没有更好的选择(无需重复自己)?
编辑 我想我解决了:
const _translateProps=(propsToBeTransLated,translate,props)=>{
const ownProps=Object.assign({},props)
propsToBeTransLated.forEach(p=>{
if(ownProps.hasOwnProperty(p)){
ownProps[p]=translate(ownProps[p])
}
})
return ownProps
}
export function withTranslatedProps(WrappedComponent,propsToBeTransLated) {
//propsToBetranslated is array with all props which will be given via keys
let retrieveProps=propsToBeTransLated?_translateProps.bind(null,propsToBeTransLated):(context,props)=>({translate:context,...props})
return React.forwardRef((props, ref) => {
console.log("render contextconsumer")
return (
<TranslatorContext.Consumer>
{context => (
<WrappedComponent {...retrieveProps(context,props)} ref={ref} />
)}
</TranslatorContext.Consumer>)
})
}
有其他可能更好的解决方案的人吗?
答案 0 :(得分:1)
您可以通过Translate HOC重复使用,也可以使用相同的HOC添加选项。
与Translate HOC一起使用:
/* function that translate the propsToBeTransLated */
const translateProps = (propsToBeTransLated, translate, props) =>
propsToBeTransLated.reduce((translatedProps, prop) => {
if(props.hasOwnProperty(prop))
translatedProps[prop] = translate(props[prop]);
return translatedProps;
}, {});
export function withTranslatedProps(WrappedComponent, propsToBeTransLated = []) {
// HOC inside HOC
const addTranslationsToProps = WrappedComponentWithContext =>
React.forwardRef((props, ref) => (
<WrappedComponentWithContext
{...props}
{...translateProps(propsToBeTransLated, props.translate, props)}
ref={ref}
/>
)
);
// first call withTranslate to add the context
return addTranslationsToProps(withTranslate(WrappedComponent));
}
向withTranslate HOC添加选项
const translateProps = (propsToBeTransLated, translate, props) =>
propsToBeTransLated.reduce((translatedProps, prop) => {
if(props.hasOwnProperty(prop))
translatedProps[prop] = translate(props[prop]);
return translatedProps;
}, {});
export function withTranslate(WrappedComponent, options) {
const { propsToBeTransLated = [] } = options;
return React.forwardRef((props, ref) => (
<TranslatorContext.Consumer>
{context => (
<WrappedComponent
{...props}
{...translateProps(propsToBeTransLated, context, props)}
translate={context}
ref={ref}
/>
)}
</TranslatorContext.Consumer>
));
}