首页 > 解决方案 > 在函数内反应运行函数

问题描述

我正在尝试handleOpenDropDownfastening.value更新为drill_free.

我遇到的问题是,当用户选择一个选项并selectFastening运行并设置fastening.value为“drill_free”时,它无法识别该值已更新为,drill_free直到选择另一个选项然后该函数将运行,所以它运行后它应该。

如何更改我的selectFastening功能,以便何时fastening.value设置drill_free为该handleOpenDropDown功能将立即运行

还原商店

fastening { value: '', valid: '' }

紧固.js

export const settingDropName = 'fastening';
export const otherDropdownName = 'dimensions';    

class SettingDropFastening extends React.Component {
  constructor() {
    super()
    this.state = {
      showAlias: '',
      showImage: false,
    }
  }

  handleOpenDropdown = () => {
    this.props.close('fastening')
    this.props.openDropdownAlt('dimensions')
  }

  selectFastening = (fastening, name) => {
    this.props.selectFastening(fastening)
    this.props.selectedFastening.value === 'drill_free' && this.handleOpenDropdown()
  }

  closeDropdown = () => {
    this.props.showConfirmation ? this.props.closeDropdownWithConfirmation() : this.props.closeDropdown();
  }

  handleShowMontageImage = (alias) => {
    this.setState(prevState => ({
        //if same then reset otherwise assign new cat
      showAlias: prevState.showAlias === alias ? false : alias,
    }))
  }

  close = (name) => {
    this.props.close(name)
  }

  render() {
    const plissee = this.props.designation.alias === 'plissee'
    const rollo = this.props.designation.alias === 'rollo'
    const lamellen = this.props.designation.alias === 'lamellen'
    const holzJalousie = this.props.designation.alias === 'holzJalousie'
    const aluJalousie = this.props.designation.alias === 'aluJalousie'


    return (
      <SettingDrop
        title={"Befestigung"}
        closeDropdown={() => this.close('')}
        openDropdown={this.props.openDropdown}
        isOpen={this.props.isOpen}
        isHidden={this.props.isHidden}
        isValid={this.props.isValid}
        icon={<Befestigung />}
        option={
          (this.props.fastening.isValid && this.props.fastening.value)
          ?
          <span>
            <SelectedOptionLabel>Befestigung</SelectedOptionLabel>
            <SelectedOption>{this.props.fastening.value.name}</SelectedOption>
          </span>
          :
          <SelectedOptionSelect />
        }
        option2={
          ((this.props.fastening.isValid && this.props.fastening.value) && this.props.fastening.value.value !== null ||
          ((this.props.fastening.isValid && this.props.fastening.value) && this.props.fastening.value.value === null) &&
          this.props.selectedLateralGuidance === true) &&
          <span>
            <SelectedOptionLabel>Aufpreis</SelectedOptionLabel>
            <SelectedOption>
            {(this.props.fastening.value.type === ATTRIBUTE_TYPE_PRICE && this.props.fasteningCount) &&
              <span>
                {formatPrice(this.props.fastening.value.value * this.props.fasteningCount + (this.props.selectedLateralGuidance === true && 5))}
              </span>
            }
            {(this.props.fastening.isValid && this.props.fastening.value) &&
            (this.props.fastening.value.value === null && this.props.selectedLateralGuidance === true) &&
              <span>
                {formatPrice(5)}
              </span>
            }
            </SelectedOption>
          </span>
        }
      >
        <div>
        {console.log('selected fastening',this.props.selectedFastening)}
          {this.props.lateralGuidanceIsSelectable &&
            <div>
              <ShowSelect
                placeholder="Alle anzeigen"
                cat="Zusätzliche Seitenführung"
                width={220}
                options={[{
                  label: <span>Ja &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>(Aufpreis 5,00 €)</strong></span> ,
                  value: 1
                }, {
                  label: 'Nein',
                  value: 0
                }]}
                value={this.props.selectedLateralGuidance ? 'Ja' : 'Nein'}
                onChange={ newValue => this.props.selectLateralGuidance(newValue && !!newValue.value) }
                designation={this.props.designation}
              />

            </div>
          }

          <div>
            <Description>Bitte wählen Sie Ihre Befestigungsart:</Description>
            <Grid>
              {this.props.fastenings.filter(fastenings => this.props.operationType === 'Schnurzug'
                ? (fastenings.alias !== 'bead_embroidery_fix' && fastenings.alias !== 'bead_embroidery_front_fix' && fastenings.alias !== 'drill_free')
                : fastenings)
                .map(fastening =>
                <Cell
                  key={fastening.alias}
                >
                <div>
              </div>
                  <ImageWrap
                    active={(this.props.fastening.isValid && this.props.fastening.value) && fastening.alias === this.props.fastening.value.alias}
                    name={fastening.name}
                    height={200}
                    key={fastening.alias}
                    onClick={
                      ((this.props.fastening.isValid && this.props.fastening.value) && fastening.alias === this.props.fastening.value.alias
                      ? null
                      : () => this.selectFastening(fastening.alias)
                      || this.props.selectedFastening.value === 'drill_free' ? () => this.handleOpenDropdown() : null
                      )
                    }
                    src={cdn(`images/fastenings/${this.props.designation}/${fastening.alias}.png`)}
                    alt={fastening.name}
                    price={((this.props.fastening.isValid && this.props.fastening.value) && fastening.alias === this.props.fastening.value.alias) &&
                    <div> {`Anzahl Montageteile: ${this.props.fasteningCount}`} &nbsp;&nbsp;&nbsp;<strong>{`(Aufpreis: ${formatPrice(fastening.value * this.props.fasteningCount)})`}</strong> </div>
                    }
                    designation={this.props.designation}
                    montageImages={
                      <div>
                        <MontageIcon onClick={() => this.handleShowMontageImage(fastening.alias)}>?</MontageIcon>
                          {montageImages.filter(montageImage => montageImage.name === this.props.designation).map((montageImage, index) =>
                            <div key={index}>
                               {(this.props.selectedModel !== 70 || this.props.selectedModel !== 52 )  &&
                                montageImage.images.filter((img => img.alias === fastening.alias && this.state.showAlias === img.alias))
                                .map((img, index) =>
                                  <MontageImageWrap key={index}>
                                    <MontageImage
                                      src={cdn(`images/montageparts/${this.props.designation}/${img.montageImg}`)}
                                      alt={fastening.name}
                                    />
                                  </MontageImageWrap>
                                )
                              }
                              {(this.props.selectedModel === 70 || this.props.selectedModel === 52 ) &&
                                 montageImage.images50.filter((img => img.alias === fastening.alias && this.state.showAlias === img.alias))
                                  .map((img, index) =>
                                    <MontageImageWrap key={index}>
                                      <MontageImage
                                        src={cdn(`images/montageparts/${this.props.designation}/${img.montageImg}`)}
                                        alt={fastening.name}
                                      />
                                    </MontageImageWrap>
                                  )
                              }
                            </div>
                          )}
                       </div>
                    }
                  />
                </Cell>
              )}
            </Grid>
          </div>
        </div>
      </SettingDrop>
    );
  }
};

const mapStateToProps = (state) => {

  const isOpen = state.ui.productSettings.openDropdown === settingDropName;
  const isHidden = !!state.ui.productSettings.openDropdown && !isOpen;
  const isValid = fasteningIsValid(state);

  return {
    designation: {
      ...mapDesignationName(state.model.designation.alias),
      alias: state.model.designation.alias
    },
    isOpen,
    isHidden,
    isValid,
    fastening: {
      value: getFastening(state),
      isValid: state.model.fastening.isValid
    },
    operationType: state.model.operationType.value,
    fasteningCount: getFasteningCount(state),
    showConfirmation: isValid ? false : !!state.model.fastening.value,
    fastenings: getFastenings(state),
    lateralGuidanceIsSelectable: !!getLateralGuidance(state, false),
    selectedLateralGuidance: state.model.lateralGuidance.value,
    fasteningCount: getFasteningCount(state),
    fasteningPrice: Number((getFastening(state) || {}).value) || 0,
    designation: state.model.designation.alias,
    selectedModel: state.model.model,
    selectedFastening: state.model.fastening
  };
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({
    ...settingDropActions,
  }, dispatch);
};

export default connect(mapStateToProps, mapDispatchToProps)(SettingDropFastening);

标签: javascriptreactjsredux

解决方案


这里:

selectFastening = (fastening, name) => {
    this.props.selectFastening(fastening)
    this.props.selectedFastening.value === 'drill_free' && this.handleOpenDropdown()
  }

第二行的 props 还没有更新,所以 React 仍然在那里使用旧的 props。

你可以把这个逻辑:

   this.props.selectedFastening.value === 'drill_free' && this.handleOpenDropdown()

componentDidUpdate. 但是,如果之后触发了其他事情componentDidUpdate并且value仍然是drill_free,它将再次调用该handleOpenDropDown()函数。因此,您可能想以某种方式保护自己免受这种情况的影响。

您可以检查这个(较旧的)相关问题,它使用componentWillReceiveProps,但您可以应用相同的想法使用componentDidUpdate


推荐阅读