在课堂外向地图回调发送道具

时间:2019-03-21 15:54:48

标签: javascript reactjs ecmascript-6

我正在与React合作。我有一个带有 state 和一个 array 的类。列表数组,我可以制作一个.map对其进行迭代。

 {this.state.list.map((e, i) => {/*do your stuffs*/}

现在,我想将逻辑发送到地图之外,原因是,我有另一个组件应呈现相同的内容,但具有不同的数组。

问题,我从类中调用方法。所以,我的问题是,如何在类之外创建一个可以访问类方法的函数?

这是我到目前为止所拥有的:

  {this.state.list.map(mapping)}

以及映射功能:

const mapping = (e, i) =>  {
  return (  
    <div className='form-row' key={i}>
      <SelectInput 
        uid={i}
        data = {e.red.toString()}
        handleChange = {this.handleChange}
        options = {this.props.options}
        label = {'Red Social'}  col = {'col-md-5'}
        name = {'red'} />
        (...)

错误:

  

未捕获的TypeError:无法读取未定义的属性'handleChange'

我希望更改手柄的方法相对于当前类。在一个类中,我必须使用特定的功能来修改特定的状态,而在其他类别中,其他功能则需要执行其他操作。

2 个答案:

答案 0 :(得分:2)

Array.prototype.map()接受可选的thisArg作为第二个参数:

  

执行this时用作callback的值。

像这样调用您的mapping函数:

this.state.list.map(mapping, this)

...和mapping将与您的组件一起称为this


然后将您的mapping函数更改为标准函数而不是箭头函数,以便它不会自动捕获"the this value of the enclosing lexical scope"

const mapping = function (e, i) {  // <= normal function
  return (  
    <div className='form-row' key={i}>
      <SelectInput 
        uid={i}
        data = {e.red.toString()}
        handleChange = {this.handleChange}  // <= 'this' is your component
        options = {this.props.options}
        label = {'Red Social'}  col = {'col-md-5'}
        name = {'red'} />
        (...)

...和this将引用您在mapping中的组件。

答案 1 :(得分:1)

两个类应使用依赖于它们的属性的同一段代码,这意味着类应从基类继承,并且公共方法应绑定到上下文:

class Base extends Component {
  mapping = this.mapping.bind(this);
  mapping(e, i) { ... }
}

class Foo extends Base {
  render() {
    ...
    {this.state.list.map(this.mapping)}
    ...
  }
}

针对此类情况,React正式宣传composition instead of inheritance。应该提取可重用的功能,以将接受公共参数作为道具的单独组件提取出来:

const SelectInputList = ({ list, handleChange, options }) => {
  return list.map((e, i) => (
    <div className='form-row' key={i}>
      <SelectInput 
        uid={i}
        data = {e.red.toString()}
        handleChange = {handleChange}]
        options = {options}
        ...
});