1

我正在尝试使用 ES6 语法构建一个 ReactJS 高阶组件。这是我的尝试:

export const withContext = Component =>
    class AppContextComponent extends React.Component {
        render() {
            return (
                <AppContextLoader>
                     <AppContext.Consumer>
                        {context => <Component {...props} context={context} />}
                    </AppContext.Consumer>
               </AppContextLoader>
            );
        }
    };

在这里,AppContextLoader从数据库中获取上下文并将其提供给上下文,如下所示:

class AppContextLoader extends Component {
  state = {
    user: null,
  };

  componentWillMount = () => {
    let user = databaseProvider.getUserInfo();
    this.setState({
      user: user
      });
  };


  render = () => {
    return (
      <AppContext.Provider value={this.state}>
        {this.props.children}
      </AppContext.Provider>
    );
  };
}

export default AppContextLoader;

和用法:

class App extends Component {
    static propTypes = {
         title: PropTypes.string,
         module: PropTypes.string
    }

    render = () => {
        return (
                withContext(
                <Dashboard
                    module={this.props.module}
                    title={this.props.title}
                />
                );

export default App;

出于某种原因,我的包装组件 ( Dashboard) 没有获得我的context财产,只有原始的 (titlemodule)。

如何使用 ES6 语法正确编写 HOC?

4

3 回答 3

1

您没有正确使用 HOC,您需要传递组件而不是组件实例。从渲染中调用 HOC 也是一个不好的模式,因为每次渲染都会返回一个新组件,您必须编写

const DashboardWithContext = withContext(Dashboard);
class App extends Component {
    render = () => {
        return (
                <DashboardWithContext
                    module={"ADMIN"}
                    title={"MY APP"}
                />
        )
    }
}

export default App;

此外,withContext HOC由于返回的组件是一个类,因此您可以访问 props{...this.props}而不是{...props},但是使用功能组件是有意义的,因为您实际上并没有使用生命周期方法

 export const withContext = Component => (props) => (
            <AppContext.Consumer>
                {context => <Component {...props} context={context} />}
            </AppContext.Consumer>
        );

工作代码沙盒

于 2018-04-27T06:09:31.740 回答
0

你有几个问题:

  1. 您没有正确使用 Context API - 创建上下文是为了使用 aProvider与一个或多个共享值Consumers- 您正在使用 hoc 创建一个新的ProviderConsumer.

  2. 从您的示例中,您不需要使用Context- 将 hoc 用于新的使用数据 -withUserData

  3. 你应该使用this.props而不是道具

  4. 在用法部分,您将元素而不是组件传递给 hoc

  5. 你没有得到道具withContext

解决方案

export const withUserData = BaseComponent =>
  class AppContextLoader extends Component {
    state = {
      user: null,
    };

    componentWillMount = () => {
      let user = databaseProvider.getUserInfo();
      this.setState({
        user: user
      });
    };


    render = () => {
      return (
        <BaseComponent {...this.props} {...this.state} />
      );
    };
  }

和用法:

class App extends Component {
    static propTypes = {
         title: PropTypes.string,
         module: PropTypes.string
    }

    render = () => {
        return (
                  <EnhancedDashboard
                    module={this.props.module}
                    title={this.props.title}
                  />
                );
     }


const EnhancedDashboard = withUserData(Dashboard)

export default App;
于 2018-08-01T09:18:28.257 回答
0

它应该是this.props

<Component {...this.props}

这应该对你有用:

render() {
  const props = this.props;
  return (
    <AppContext.Consumer>
      {context => <Component {...props} context={context} />}
    </AppContext.Consumer>
  );
}
于 2018-04-27T06:15:28.753 回答