【问题标题】:React onChange is not a function when passing method as props to child component将方法作为道具传递给子组件时,React onChange 不是函数
【发布时间】:2020-02-10 09:32:05
【问题描述】:

我在将一个方法向下传递到几个较低的子组件时遇到问题。我需要在父组件中保持状态,因此将方法向下传递以更改父组件中的状态值的原因。现在我知道这个问题之前已经回答过好几次了,但是我读到的所有内容都不起作用?

这是我想要做的:

父方法代码(OrderView.js):

 handleChargesDateChange = (e) => {
    const date = e.target.value;
    const chargeId = e.target.name;
    console.log(date);
    this.setState({
        updatedChargeDates: [
            ...this.state.updatedChargeDates,
            {[chargeId]: date}
        ]
    })
}

然后,此方法在 render() 中作为 props 传递:

 <Grid.Row>
            <Grid.Column width={16}>
                <OrderSummary
                    order={this.state.order}
                    fuelTypes={this.state.fuelTypes}
                    vehicleClasses={this.state.vehicleClasses}
                    deviceTypes={this.state.deviceTypes}
                    chargeTypes={this.state.chargeTypes}
                    featureTypes={this.state.featureTypes}
                    itemGroups={this.state.itemGroups}
                    itemTypes={this.state.itemTypes}
                    **updateChargeDates={this.handleChargesDateChange}**
                />
            </Grid.Column>
        </Grid.Row>

然后在OrderSummary 中,我收到如下的道具并再次将其传递给另一个子组件:

const updateChargeDates = this.props;

    console.log("Itemsssss " + this.props.order.items);
    const panes = [];
    if (this.props.order.devices.length > 0) {
        panes.push({
            menuItem: 'Devices', render: () => <DevicesTab
                devices={this.props.order.devices || []}
                fuelTypes={this.props.fuelTypes || []}
                vehicleClasses={this.props.vehicleClasses || []}
                deviceTypes={this.props.deviceTypes || []}
                chargeTypes={this.props.chargeTypes || []}
                featureTypes={this.props.featureTypes || []}
            />
        });
    }

    if (this.props.order.items.length > 0) {
        panes.push({
            menuItem: 'Additional Items', render: () => <ItemsTab
                items={this.props.order.items || []}
                itemGroups={this.props.itemGroups || []}
                itemTypes={this.props.itemTypes || []}
                chargeTypes={this.props.chargeTypes || []}
                **updateChargeDates={updateChargeDates}**
            />
        })
    }

然后,我将它传递给另一个子组件到 ItemsTab 组件中:

 render() {
    const { items, itemGroups, itemTypes, chargeTypes, updateChargeDates } = this.props;
    return <Tab.Pane className='no-border'>
        {items.length > 0 && <Grid>
            <Grid.Row columns={2}>
                <Grid.Column>
                    <ItemGroup
                        itemOrder={items[this.state.currentItem] || {}}
                        itemGroups={itemGroups || []}
                        itemTypes={itemTypes || []}
                    />
                </Grid.Column>
                <Grid.Column>
                    <Charges
                        charges={items[this.state.currentItem].charges || {}}
                        chargeTypes={chargeTypes || []}
                        handleDateChange={this.handleChange}
                        **updateChargeDates={updateChargeDates}**
                    />
                </Grid.Column>
            </Grid.Row>

最后,在Charges 组件中,我尝试使用该方法来简单地更新日期:

 render() {
 const {charges, chargeTypes, updateChargeDates} = this.props;
 if (charges.length === 0) { return null; }

return <Form>
    <h3>Charges</h3>
    {charges.map(charge => {
        console.log(charge);
        const chargeType = chargeTypes.find(type => type.code === charge.type) || {};
        return <Grid>
            <Grid.Row columns={2}>
                <Grid.Column>
                    <Form.Input
                        key={charge.id}
                        label={chargeType.description || charge.type}
                        value={Number(charge.amount).toFixed(2)}
                        readOnly
                        width={6} />
                </Grid.Column>
                <Grid.Column>
                    <DateInput
                        name={charge.id}
                        selected={this.state.newDate}
                        **onChange={updateChargeDates}**
                        value={charge.effectiveDate}
                    />
                </Grid.Column>
            </Grid.Row>
        </Grid>
    })}
    <Divider hidden />
    <br />
</Form>
}

注意:我用** 突出显示了我关心的代码位

我在浏览器控制台中收到的错误如下:

现在我知道,当你没有 bind 类的方法时,通常会发生此错误,但我使用的是 => ES6 语法,我认为不需要这样做?我什至尝试将绑定添加到父组件,如下所示: this.handleChargesDateChange = this.handleChargesDateChange.bind(this);

但这又是行不通的。我尝试了以下资源,但没有运气:

Passing props down to childs

OnCHange is not a function

有人可以解释一下我哪里出错了吗?我现在尝试了几个小时,但没有运气:/

谢谢!

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    你在这里错误地分配了一个道具:

    const updateChargeDates = this.props;
    

    改成

    const { updateChargeDates } = this.props;
    

    const updateChargeDates = this.props.updateChargeDates;
    

    【讨论】:

    • 您好,感谢您的快速回复,但这仍然不起作用:/
    • @AlexanderDunn 请试试我的回答:]
    • @AlexanderDunn 你还遇到同样的错误吗?
    • 是的,仍然出现同样的错误。这不是因为类是默认类吗?像这样:export default class OrderView extends Component
    • 如果是这样的话,你会得到一个不同的错误。您是否在某处有包含完整代码的存储库/沙箱?似乎您在某种程度上仍未正确分配/传递updateChargeDates
    【解决方案2】:

    你没有以正确的方式破坏 updateChargeDates 属性,试试这个;

    const { updateChargeDates } = this.props;
    

    【讨论】:

      【解决方案3】:

      目前无法测试代码,但这是我的猜测:

      const { updateChargeDates } = this.props;
      

      而不是

      const updateChargeDates = this.props;
      

      OrderSummary


      OrderView.js中也可以更改:

      handleChargesDateChange = (e) => () => {
          const date = e.target.value;
          const chargeId = e.target.name;
          console.log(date);
          this.setState({
              updatedChargeDates: [
                  ...this.state.updatedChargeDates,
                  {[chargeId]: date}
              ]
          })
      }
      

      【讨论】:

      • 这里有什么区别?
      • 嗯...有用吗?据我了解,如果您将父级参数作为onClick/onChange 函数传递给子级,则必须使用柯里化函数
      • 根据您的错误,您的updateSelectedDate 似乎有另一个问题
      【解决方案4】:

      现在我知道当你不将方法绑定到类时通常会发生此错误,但我使用的是 => ES6 语法,我认为不需要这样做?

      你是对的,ES6 语法不需要绑定函数。 问题是正如其他人所说,您错误地解构 updateChargeDates,您需要将其包装在 {} 中才能对其进行解构。

      const { updateChargeDate } = this.props;

      如果您想了解更多关于 ES6 解构的信息,请查看 this

      错误信息明确指出错误在 DateInput.js 的第 19 行。这是您创建的自定义类,还是来自第三方库?您需要检查该类是否确实包含 on-change 方法,因为错误表明它不是函数。

      【讨论】:

      • DateInput 是一个接受 onChange 的自定义类。我知道这一点,因为当我最初在子类中实现方法时,我得到了我的预期。
      猜你喜欢
      • 2022-01-24
      • 2021-05-26
      • 2019-07-03
      • 2020-04-22
      • 2019-12-31
      • 2020-03-12
      • 2018-08-01
      • 2018-01-13
      相关资源
      最近更新 更多