javascript React:在父组件中触发重置功能时,子组件未获得更新值

sqougxex  于 2023-01-16  发布在  Java
关注(0)|答案(2)|浏览(176)

更新:

我认为问题是子组件2没有重新渲染,因为在父组件中触发handleReset()时有相同的 prop 。但我如何使它们重新渲染?我尝试使用useEffect,但没有任何React。

我挣扎了几个小时与以下问题:我有一个父组件,其中一些值从useState传递到子组件1(CustomerData),然后传递到子组件2(-AddressForm和-CustomerForm)。
我的问题是,当父组件的handleReset()被触发时,child2(AddressForm和CustomerForm)的值没有更新,我不明白为什么。我认为当我重置值时,child2组件没有重新呈现,不知何故,我需要以某种其他方式传递handleReset()的set钩子中的声明。
如果有人能帮我解决这个问题,请。以下是我的组件:

父组件:

function WidgetCustomerData(props): JSX.Element {
    const customerDataTest = {
        customerFirstName: 'firstNameTest',
        customerLastName: 'lastNameTest',
        customerPhone: '1313212',
        customerEmail: 'test@test.com',
        customerAddress: 'Musterstraße',
        customerAddressNo: '12',
        customerZip: '80335',
        customerCity: 'Berlin',
        deviceAddress: 'Straße',
        deviceAddressNo: '152',
        deviceZip: '32214',
        deviceCity: 'Hamburg',
    };

  const [customerData, setCustomerData] = useState({
    addressValue: customerDataTest.customerAddress,
    addressValueNr: customerDataTest.customerAddressNo,
    addressValueZip: customerDataTest.customerZip,
    addressValueCity: customerDataTest.customerCity,
    customerFirstName: customerDataTest.customerFirstName,
    customerLastName: customerDataTest.customerLastName,
    customerPhone: customerDataTest.customerPhone,
    customerEmail: customerDataTest.customerEmail,
    deviceAddress: customerDataTest.deviceAddress,
    deviceAddressNo: customerDataTest.deviceAddressNo,
    deviceZip: customerDataTest.deviceZip,
    deviceCity: customerDataTest.deviceCity
  })

  const handleClose = () => {
    props.handleClose();
}

    const handleSubmit = async (e) => {
        e && e.preventDefault();
        const formUrl = 'https://fetch.mock/widget-customer-data/addCustomerData';
        const formData = new FormData(e.target);
        for (const [name, value] of formData) {
            console.log(`${name}: ${value}`);
        }

        const response = await fetch(formUrl.toString(), {
            method: 'POST',
            body: formData,
            credentials: 'same-origin',
        });

        const data = await response.json();
    };

    const handleReset = () => {
        console.log('handleReset ----');
        
      setCustomerData({
      addressValue: customerDataTest.customerAddress,
      addressValueNr: customerDataTest.customerAddressNo,
      addressValueZip: customerDataTest.customerZip,
      addressValueCity: customerDataTest.customerCity,
      customerFirstName: customerDataTest.customerFirstName,
      customerLastName: customerDataTest.customerLastName,
      customerPhone: customerDataTest.customerPhone,
      customerEmail: customerDataTest.customerEmail,
      deviceAddress: customerDataTest.deviceAddress,
      deviceAddressNo: customerDataTest.deviceAddressNo,
      deviceZip: customerDataTest.deviceZip,
      deviceCity: customerDataTest.deviceCity
    })
    };

    return (
        <div className="customer-data">
            <Dialog
                onClose={handleClose}
        open={props.open}
                aria-labelledby="customized-dialog-title"
                PaperProps={{
                    style: { borderRadius: 20, minWidth: '80%', maxHeight: 'fit-content' },
                }}>
                <DialogTitle id="customized-dialog-title" onClose={handleClose} />
                <Typography style={{ marginTop: 20, paddingLeft: 48, fontSize: 32, fontWeight: 600 }}>Kundendaten bearbeiten</Typography>
                {/* <DialogContent> */}
                    <form onSubmit={handleSubmit}>
            <div style={{ paddingLeft: 48, paddingRight:48 }}>
              <CustomerData
                customerData={customerData}
              />
            </div>
                        <DialogActions>
                            <ResetButton onClick={handleReset} variant="contained" color="primary">
                                Reset
                            </ResetButton>
                            <SaveButton type="submit" variant="contained" color="primary">
                                Save
                            </SaveButton>
                        </DialogActions>
                    </form>
                {/* </DialogContent> */}
            </Dialog>
        </div>
    );
}
export default WidgetCustomerData;

儿童1

export default ({nextStepAction, customerData }: MoleculeSystemManagementCustomerDataProps): JSX.Element => {

  return (
    <div className='c-data'>
      <CustomerForm customerData={customerData} />
      <AddressForm formId='customer' customerData={customerData} />
    </div>
  );
}

儿童2

function AddressForm({formId customerData }): JSX.Element {

  const classes = useStyles();

  const { addressValue, addressValueNr, addressValueZip, addressValueCity, deviceAddress, deviceAddressNo, deviceZip, deviceCity } =  customerData; 

  return (
    <Grid container className={classes.borderedRow}>
      <Grid item xs={12} sm={6} md={3} className={classes.formColumn}>
        <div>        
        <InputField type='label' id='address' name={`${formId}-address`} value={formId === 'customer' ? addressValue : deviceAddress} label={'Street'} />
        </div>
      </Grid>

      <Grid item xs={12} sm={6} md={3} className={classes.formColumn}>        
        <InputField type='label' id='city' name={`${formId}-city`} value={formId === 'customer' ? addressValueNr : deviceAddressNo} label={'Number'} />
      </Grid>

      <Grid item xs={12} sm={6} md={3} className={classes.formColumn}>        
        <InputField type='label' id='state' name={`${formId}-state`} value={formId === 'customer' ? addressValueZip : deviceZip} label={'ZIP'} />
      </Grid>

      <Grid item xs={12} sm={6} md={3} className={classes.formColumn}>        
        <InputField type='label' id='zip' name={`${formId}-zip`} value={formId === 'customer' ? addressValueCity : deviceCity} label={'ORT'} />
      </Grid>
    </Grid>
  );
}
export default AddressForm;
tp5buhyn

tp5buhyn1#

我认为问题的发生是因为状态只传递给了第一个子组件。
如果你仔细观察,你会发现在从child(1)到child(2)的过程中,没有状态处理它,如果它不是状态,React不会更新你的props的值。
也许,你只需要在第一个子节点中创建一个状态。

儿童1

export default ({nextStepAction, customerData }: MoleculeSystemManagementCustomerDataProps): JSX.Element => {
      const [addressIsDifferent, setAddressIsDifferent] = useState(true);
      const [customerDataState, setCustomerDataState] = useState(customerData)
    
      return (
        <div className='c-data'>
          <CustomerForm customerData={customerData} />
          <AddressForm formId='customer' customerData={customerDataState} />
        </div>
      );
    }

额外提示:我不知道您项目的用例是什么,但我强烈建议您看一看ReactContext API
如果您需要通过需要相同数据的组件传递数据并执行内聚函数,那么使用它是一个很好的主意。
在一个典型的React应用程序中,数据是通过props自上而下(父到子)传递的,但是这种用法对于应用程序中许多组件所需的某些类型的props(例如区域设置首选项、UI主题)来说可能很麻烦。上下文提供了一种在组件之间共享值的方法,而不必显式地通过树的每一级传递prop。

mum43rcc

mum43rcc2#

它看起来象你正在设置状态到相同的数据作为它是initialised.你initialised它与customerDataTest并且然后设置它到customerDataTest .同样的事情

相关问题