标签: higher-order-components

将React上下文通过HOC传递给包装组件

有没有办法可以通过React高阶组件将上下文传递给它包装的组件?

我有一个HOC从其父级接收上下文,并利用该上下文执行基本的通用操作,然后包装一个也需要访问相同上下文以执行操作的子组件.例子:

HOC:

export default function withACoolThing(WrappedComponent) {
  return class DoACoolThing extends Component {
    static contextTypes = {
      actions: PropTypes.object,
    }

    @autobind
    doAThing() {
      this.context.actions.doTheThing();
    }

    render() {
      const newProps = {
        doAThing: this.doAThing,
      };

      return (
        <WrappedComponent {...this.props} {...newProps} {...this.context} />
      );
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

包裹组件:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { autobind } from 'core-decorators';
import withACoolThing from 'lib/hocs/withACoolThing';


const propTypes = {
  doAThing: PropTypes.func,
};

const contextTypes = {
  actions: …
Run Code Online (Sandbox Code Playgroud)

javascript ecmascript-6 reactjs redux higher-order-components

6
推荐指数
1
解决办法
1301
查看次数

如何在React中将HTML元素传递给高阶函数(HOC)?

我经常使用HOC为现有的React组件提供附加功能,这非常简单:

import Component from '/path/to/Component';
import higherOrderComponent from '/path/to/higherOrderComponent';

const EnhancedComponent = higherOrderComponent(Component);
Run Code Online (Sandbox Code Playgroud)

但是,我需要包装一个简单的HTML input,它不作为独立的React组件存在。我试过了

const EnhancedInput = higherOrderComponent(<input />);
Run Code Online (Sandbox Code Playgroud)

并得到以下错误:

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Run Code Online (Sandbox Code Playgroud)

如何正确传递输入?

jsx reactjs higher-order-components

6
推荐指数
2
解决办法
950
查看次数

React:高阶组件的懒惰评估?

我们正在尝试自定义 HOC 的参数(特别是react-graphql)。由于这个特定库 HOC 的工作方式,我们无法在调用 HOC 后影响组件状态(查询和选项)。

在像connect()Redux这样的传统 HOC 工厂中,所有包含的逻辑都会立即应用——这对我们来说还为时过早。相反,我将原始 HOC ( applyOriginalHOC()) 的应用推迟到从该组件构建第一个实例之前。

export function applyLazyHOC(args) {
  return function wrap(WrappedComponent) {
    let ComponentWithLazyHOC; // Closed-over value is scoped to component
    class LazyHOC extends Component {
      constructor() {
        super();
        // Lazy initialising of HOC to give customisations an opportunity to be registered
        if (!ComponentWithLazyHOC) {
          ComponentWithLazyHOC = applyOriginalHOC(
            // Adds customisations which have been registered by third party code
            myCustomization(args)
          )(WrappedComponent);
        }
      }
      render() { …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs higher-order-components

5
推荐指数
0
解决办法
515
查看次数

将 React 路由渲染函数包装在 HOC 中

我正在使用 React-Router 4 创建一些路由。(它使用官方文档PrivateRoute中的组件,但这与这个问题无关。)

<HashRouter>    
    <Switch>
        <PrivateRoute exact path='/' component={Wrapper(Home)} />
        <Route exact path='/login' render={(props) => <Login authenticate={this.authenticate} {...props} />} />
        <PrivateRoute exact path='/clients' component={Wrapper(Clients)} />
    </Switch>
</HashRouter>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的HomeClients组件被包装在HOC中。目前这没有任何作用:

const Wrapper = (Page) => {
    return (props) => (
        <div className="page">
            <p>This should be on every page</p>
            <Page {...props} />
        </div>
    );
}
Run Code Online (Sandbox Code Playgroud)

这很好用。我不知道如何将Login路线包装在同一个 HOC 中。我试过了

<Route exact path='/login' render={(props) => Wrapper(<Login authenticate={this.authenticate} {...props} />)} />
Run Code Online (Sandbox Code Playgroud)

但这会返回错误:

Route.render():必须返回有效的 React …

javascript reactjs react-router higher-order-components

5
推荐指数
1
解决办法
2651
查看次数

React HOC——给封装的组件添加事件监听器

我正在尝试创建一个 HOC,它使常规功能组件 »Touchable«。

所以我有一个这样的 HOC:

const Touchable = (Component, handler) => {
  const T = ({props, children}) => {
    const Instance = React.createElement(
      Component, 
      {
        ...props,
        onTouchStart: (e) => handler.touchStart(e),
        /*more listeners*/
      }, children);
  }

  return T;
}
Run Code Online (Sandbox Code Playgroud)

另一个像这样的组件:

const Button = ({props, children}) => <div>…</div>;

export default Touchable(Button, {touchStart: () => {}});
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

<Button>Hallo</Button>
Run Code Online (Sandbox Code Playgroud)

结果(反应开发人员面板):

<Button onTouchStart={…}>
  <div>…</div>
</Button>
Run Code Online (Sandbox Code Playgroud)

但我真正想要的是:

<Button>
  <div onTouchStart={…}>…</div>
</Button>
Run Code Online (Sandbox Code Playgroud)

我试图克隆实例,但不知何故我没有运气。我怎样才能做到这一点?

reactjs higher-order-components

5
推荐指数
1
解决办法
4522
查看次数

HOC中的inner函数是如何获取props的

我只是开始使用HOCin React,让我有点困惑的一件事是,在这个例子中我的内部函数如何获得props作为参数的访问权限?

const withProps = Component => (
  props => {
    return <Component {...props}/>
  }
)

export default withProps
Run Code Online (Sandbox Code Playgroud)

higher-order-functions reactjs higher-order-components

5
推荐指数
1
解决办法
1376
查看次数

仅当 props 中满足特定条件时才添加 HoC

我正在使用重组库和 HoC 为我的组件传递一堆 props。我想知道是否有办法compose在设置 HoC 之前检查 props。例如,假设我有这样的东西:

export default compose(
  withProps(props => ({
    shouldUseWithMyHoc: someCondition() // true or false
  })),
  withState('someState', 'setSomeState', ''),
  withHandlers({
    doStuff: props => evt => {
      // do stuff
    }
  }),
  withMyHoc() // should only use if `shouldUseWithMyHoc` prop is true
)(MyComponent)
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能withMyHoc仅在shouldUseWithMyHoc设置为 时使用true

我想过也许可以做一个三元组,但是进展并不顺利,当条件为假时我没有什么可以依靠的。它看起来像这样:

  export default compose (
  ...
  (props) => {(
    props.shouldUseWithMyHoc
    ? withMyHoc()
    : null)}
  )(MyComponent)
Run Code Online (Sandbox Code Playgroud)

通过使用三元,我收到以下错误:

警告:无法在未安装的组件上调用 setState(或forceUpdate)。这是一个空操作,但它表明应用程序中存在内存泄漏。要修复此问题,请在 componentWillUnmount 方法中取消所有订阅和异步任务。

我有办法完成这件事吗?如果这看起来是正确的,那么我做错了什么?

reactjs recompose higher-order-components

5
推荐指数
1
解决办法
1104
查看次数

在 Material UI 中将变量发送到 withStyles?

我有以下内容:

class StyledInput extends React.Component{


  styles = (color, theme) => ({
    underline: {
      borderBottom: `2px solid ${color}`,
      '&:after': {
        borderBottom: `2px solid ${color}`,
      }
    }
  })
  
  div = props => (
    <TextField
    placeholder="temp input"
    InputProps={{
      classes:{
        root: props.classes.underline
      },
      style:{
        height: '1.5rem',
        fontSize:'1rem',
        marginTop: '-1rem',
      }
    }}
    >
      <div>
        {props.children}
      </div>
    </TextField>
  )
  
  Styled = withStyles(this.styles('white'))(this.div)

  render(){
    return(
      <div>
        <this.Styled>{this.props.children}</this.Styled>
      </div>
    );
  }
}

export default StyledInput;
Run Code Online (Sandbox Code Playgroud)

因此,当用户单击该字段时,它会成功获取材质 UI 文本字段并将底部栏更改为白色,而不是蓝色。伟大的!

...然而...

我真正想做的是

<this.Styled color={someDefinedColor}>{this.props.children}</this.Styled>
Run Code Online (Sandbox Code Playgroud)

然后Styled看起来像这样:

Styled = (color) …
Run Code Online (Sandbox Code Playgroud)

css wrapper reactjs material-ui higher-order-components

5
推荐指数
1
解决办法
1万
查看次数

如何访问功能 HOC 中的道具?

我有类似于以下的代码:

const HOC = (props, WrappedComponent) => {
    return (
       <>
          <WrappedComponent />
          <Icon className="props.iconStyles" />
       </>
     );
};
Run Code Online (Sandbox Code Playgroud)

这实际上不是有效的代码,但您可以希望看到我正在尝试完成的工作。我希望能够通过以下方式使用它:

<HOC iconStyles="icon-stuff">
    <TheComponentIWantToWrap>
</HOC>
Run Code Online (Sandbox Code Playgroud)

我怎样才能正确地写这个,以便能够通过道具?我想我可能也需要在children这里使用,不确定。

reactjs higher-order-components

5
推荐指数
2
解决办法
6129
查看次数

Next.js:实现私有路由时,如何防止在重定向之前出现未经授权的路由/页面?

profile本质上,我为 Next.js 应用程序中的两个页面(即和)创建了一个 HOC,dashboard两个页面阻止用户在未经授权的情况下访问它们。

例子:pages/profile.js

import withAuth from "../components/AuthCheck/index";

function Profile() {
  return (
    <>
      <h1>Profile</h1>
    </>
  )
}


export default withAuth(Profile);
Run Code Online (Sandbox Code Playgroud)

我的身份验证组件/HOC:

import { useRouter } from 'next/router'
import { useUser } from '../../lib/hooks'
import { PageLoader } from '../Loader/index'

const withAuth = Component => {
  const Auth = (props) => {
    const { isError } = useUser(); //My hook which is calling /api/user see if there is a user
    const router = useRouter()


    if …
Run Code Online (Sandbox Code Playgroud)

reactjs higher-order-components next.js next-router

5
推荐指数
1
解决办法
1万
查看次数