【问题标题】:Callback from Child to Parent React从子级回调到父级 React
【发布时间】:2021-10-22 05:49:24
【问题描述】:

我对 React 很陌生,这是我在现有项目中的第一个任务..!好的,言归正传,所以有一个父组件 ContactForm.js,它有子组件 UserInfoStep.js。父组件中有一个按钮,我需要根据子组件中的切换按钮启用/禁用它。我曾尝试使用回调,但它给了我错误..

TypeError: Cannot read properties of undefined (reading 'callbackFunction')

ContactForm.js

const callbackFunction = (isChecked) => {
  //do enable/disable
this.Button.disabled = isChecked;
};

function ContactForm() {
    const [buttonState, setButtonState] = useState(true);
  const { PUID,FirstName, LastName, EurofinsLegalEntity, EurofinsBusinessUnit, StartDate, EndDate, frequency, test, exp, signed, laptop, transfer, existing, newL, categories} = state;

  const steps = [
    <UserInfoStep parentCallback = {this.callbackFunction} {...{  PUID,FirstName, LastName, EurofinsLegalEntity, EurofinsBusinessUnit, StartDate, EndDate}} />];

  return (
    <ContactFormContext.Provider value={{ dispatch }}>
  //some code removed
        <Button
         disabled={buttonState}
          type="submit"

      className={classes.button}
      color="primary"
      variant="outlined"
      onClick={e => {
        e.preventDefault();

        if (isLast) {
          handleSubmit();
        } else {
          goForward();
        }
      }}
    >
      {isLast ? "Submit" : "Next"}
    </Button>
//some code removed
</ContactFormContext.Provider>
);
}

export default ContactForm;

UserInfoStep.js

function UserInfoStep ({ PUID, FirstName, LastName, EurofinsLegalEntity, EurofinsBusinessUnit, StartDate, EndDate }) {
  const { dispatch } = useContext(ContactFormContext);
  const [checked, setChecked] = useState(false);

 const handleChange = () => {
 setChecked((prev) => !prev);

//as soon as this is checked, enable the button in contactForm
sendData(checked);
};

  const sendData = (isChecked) => {
this.parentCallback(isChecked);
//Enabled = isChecked;
};

return(
//some controls
<FormControlLabel
    control={<Switch checked={checked} onChange={handleChange} />}
  />
);

}

export default UserInfoStep;

【问题讨论】:

  • 我猜您的代码正在从类组件转换为功能组件。在 ContactForm.js 中,您正在使用状态但未定义。请编辑您的问题

标签: javascript reactjs


【解决方案1】:
  1. 您正在使用函数组件,因此无需使用this

  2. 您的状态未被使用,因为...

  3. ...您的回调函数在组件之外并试图设置不存在的this.Button

所以(这是您代码的一个非常简化的版本):将处理程序移动到组件内部,以便它可以直接更新状态,并使用button 状态通知按钮的disabled 属性哪个状态它应该在里面。

const { useState } = React;

function UserInfoStep({ handleChange }) {
  return (
    <button onClick={handleChange}>Toggle parent button</button>
  );
}

function ContactForm() {

  const [ buttonState, setButtonState ] = useState(true);

  function handleChange() {
    setButtonState(!buttonState);
  }

  return (
    <div>
      <div class="child">
        Child component&nbsp;&nbsp;
        <UserInfoStep handleChange={handleChange} />
      </div>
      <div class="parent">
      Parent component&nbsp;&nbsp;
        <button disabled={buttonState}>
          Parent button
        </button>
      </div>
    </div>
  );
};

ReactDOM.render(
  <ContactForm />,
  document.getElementById('react')
);
.child, .parent { margin: 0.5em 0 0.5em 0; }
.child button:hover { cursor: pointer; }
.parent button { background-color: #b3ffcc; }
.parent button:disabled { background-color:  #ff9980; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

【讨论】:

  • 我很抱歉我没有包含切换按钮,它之前是一个 FormControlLabel!..
  • 正如我所提到的,这是一个涵盖所有要点的非常简化的示例。你必须适应你的代码。
【解决方案2】:

您可以在 ContactForm 组件中使用一个函数来切换按钮状态。然后,您可以将该函数作为道具传递给子组件,并调用该函数来启用/禁用按钮。

在 ContactForm 组件中 例如:

const toggler = () =>{
 setButtonState(!buttonState);
}

将此切换器函数作为道具传递给子组件,并将其附加到切换按钮的 onClick 处理程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 2015-07-28
    • 1970-01-01
    相关资源
    最近更新 更多