【问题标题】:How to use this higher order component explained in the Redux Doc?如何使用 Redux Doc 中解释的这个高阶组件?
【发布时间】:2018-02-03 00:28:27
【问题描述】:

谁能帮我理解如何使用 redux 文档中解释的这个高阶组件?

我知道高阶组件是什么,我已经多次使用这种模式,但我不知道如何使用这个高阶组件。

http://redux.js.org/docs/recipes/UsingImmutableJS.html#use-a-higher-order-component-to-convert-your-smart-components-immutablejs-props-to-your-dumb-components-javascript-props

这就是它所说的......

使用高阶组件将智能组件的 Immutable.JS 属性转换为哑组件的 JavaScript 属性

需要将智能组件中的 Immutable.JS 属性映射到哑组件中使用的纯 JavaScript 属性。那是一个高阶组件 (HOC),它只是从您的智能组件中获取 Immutable.JS 道具,并使用 toJS() 将它们转换为纯 JavaScript 道具,然后将其传递给您的哑组件。

以下是此类 HOC 的示例:

import React from 'react'
import { Iterable } from 'immutable'

export const toJS = WrappedComponent => wrappedComponentProps => {
    const KEY = 0
    const VALUE = 1

    const propsJS = Object.entries(
        wrappedComponentProps
    ).reduce((newProps, wrappedComponentProp) => {
        newProps[wrappedComponentProp[KEY]] = Iterable.isIterable(
            wrappedComponentProp[VALUE]
        )
            ? wrappedComponentProp[VALUE].toJS()
            : wrappedComponentProp[VALUE]
        return newProps
    }, {})

    return <WrappedComponent {...propsJS} />
}

这就是您在智能组件中使用它的方式:

import { connect } from 'react-redux'

import { toJS } from './to-js'
import DumbComponent from './dumb.component'

const mapStateToProps = state => {
    return {
        // obj is an Immutable object in Smart Component, but it’s converted to a plain
        // JavaScript object by toJS, and so passed to DumbComponent as a pure JavaScript
        // object. Because it’s still an Immutable.JS object here in mapStateToProps, though,
        // there is no issue with errant re-renderings.
        obj: getImmutableObjectFromStateTree(state)
    }
}
export default connect(mapStateToProps)(toJS(DumbComponent))

通过在 HOC 中将 Immutable.JS 对象转换为纯 JavaScript 值,我们实现了 Dumb Component 的可移植性,但没有在 Smart Component 中使用 toJS() 对性能造成影响。

这是我的示例代码!!

哑组件

import React from 'react';

const DumbComponent = (props) => {

    const {dataList} = props;

    const renderList = (list) => {

        return list.map((value) => {
            return <li>value</li>
        })

    };

    return (
        <ul>
            {renderList(dataList)}
        </ul>
    )
};

export default DumbComponent;

智能组件

import React, { Component } from 'react';
import { connect } from 'react-redux';

import DumbComponent from './DumbComponent';

//High Order Component
import toJS from './toJS'; 

class SmartComponent extends Component {

    constructor(props) {
        super(props);
    }

    render() {
        return (
            <DumbComponent dataList={this.props.dataList} />
        );
    }

}


function mapStateToProps(states) {
    return {
        //Let's say this is immutable.
        dataList: state.dataList,
    };
}

//this is how I use Higher Order Component.
//export default connect(mapStateToProps)(SmartComponent);


export default connect(mapStateToProps)(toJS(DumbComponent));

我的问题

export default connect(mapStateToProps)(toJS(DumbComponent)); 这甚至不会导出 SmartComponent 本身。子组件为 DumbComponent 的 SmartComponent 的父组件连导出都不导出,怎么使用 SmartComponent??

请在我为这篇文章准备的示例代码中告诉我如何使用这个高阶组件。

更新

那么,这样写是正确的吗?

智能组件

import React, { Component } from 'react';
import { connect } from 'react-redux';

import DumbComponent from '../components/DumbComponent';

class SmartComponent extends Component {

  constructor(props) {
    super(props);
  }


  render() {

    return (
      <DumbComponent dataList={this.props.dataList} /> //immutable
    );

  }
}


function mapStateToProps(states) {
  return {
    dataList: state.dataList //immutable
  };
}


export default connect(mapStateToProps)(SmartComponent);

哑组件

import React from 'react';
import toJS from './higher_order_components/toJS';


const DumbComponent = (props) => {

  const {dataList} = props;

  const renderList = (list) => {

    return list.map((value) => {
      return <li>{value}</li>
    })

  };

  return (
    <ul>
      {renderList(dataList)}
    </ul>
  )

};


export default toJS(DumbComponent);

【问题讨论】:

  • 现在看起来不错 ????????
  • 谢谢!为了更好地理解,我制作了另一个示例代码,它按预期工作,所以我明白了!谢谢!

标签: reactjs redux react-redux immutable.js


【解决方案1】:

当您执行以下操作时:

let Component = connect(mapStateToProps)(OtherComponent)

Component 是“智能”的,因为它可以访问商店。您在代码中所做的就是在智能组件上加倍。

class OtherSmartComponent {
  render { return <DumbComponent {...smartProps} /> }
}
let SmartComponent = connect(mapStateToProps)(OtherSmartComponent)

这就是为什么在示例智能组件中没有中间智能组件,只有connectmapStateToPropsDumbComponent

也许值得一试:

import DumbComponent from './DumbComponent'
import toJS from './toJS'

let DumbComponentWithJSProps = toJS(DumbComponent)
let SmartComponent = connect(mapStateToProps)(DumbComponentWithJSProps)

export default SmartComponent

所以说真的,在你的代码中,SmartComponent 并不是很聪明。它只是渲染另一个哑组件的哑组件。该术语使此评论看起来非常苛刻。 ?

澄清您的评论:

如果您想要在已连接的组件和通过toJS 运行的组件之间有一个组件,那么就这样做。无需致电connect 两次:

// Dumb.js
import toJS from './toJS

class Dumb { .. }

export default toJS(Dumb)

-----------------------------------

// Smart.js
import Dumb from './Dumb'

class Smart {
  ..methods..
  render() { return <Dumb {...props} /> }
}

export default connect(mapStateToProps)(Smart)

【讨论】:

  • 我还是一头雾水……如果上面的 SmartComponent 类中有一些实例方法怎么办?如果我不导出 SmartComponent 类本身,而只是执行类似“export default connect(mapStateToProps)(toJS(DumbComponent));”之类的操作,我不会失去对 SmartComponent 类实例方法的访问权限吗?
  • 另外,我对智能组件的含义感到困惑。我认为这意味着可以访问 redux store 或使用 action creators 的组件。
  • 更新了更多信息。智能组件是一个模糊的术语。我想如果你的组件调度动作那么它也是“智能的”,但重点是你不需要多次connect
  • 对不起,我让你感到困惑...通过这两行,//export default connect(mapStateToProps)(SmartComponent);导出默认连接(mapStateToProps)(toJS(DumbComponent)); ,我不是说我要运行这两个代码,所以我注释掉了第一个。
  • 我并不困惑。您唯一需要在代码中更改的是 DumbComponent 中的导出调用。将export default DumbComponent 更改为export default toJS(DumbComponent),一切都很好。有意义吗?
猜你喜欢
  • 2017-09-11
  • 1970-01-01
  • 2017-07-20
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
  • 2018-09-14
  • 2021-02-24
相关资源
最近更新 更多