4

I am trying to run my function handleOpenDropDown when fastening.value is updated to drill_free.

The problem i'm having is that when the user selects an option and selectFastening runs and sets fastening.value to 'drill_free' it doesn't recognised that the value has been updated to drill_free until another option is selected then the function will run, so it is running after it supposed to.

How can I change my selectFastening function so that when fastening.value is set to drill_free the handleOpenDropDown function will run instantly

redux store

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

fastening.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);
3
  • What does your reducer look like? Commented Dec 18, 2018 at 14:08
  • I think you can use 'componentDidUpdate' and check if the prop value is equal to 'drill_free' and then fire the action/method you need Commented Dec 18, 2018 at 14:09
  • thanks Kabbany I think that would work, I was just wondering if there a simpler way to do this by firing the function within my fastening function Commented Dec 18, 2018 at 14:11

1 Answer 1

4

Here:

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

on the second line the props didn't get updated yet, so React still uses old props there.

You can put this logic:

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

in componentDidUpdate. However, if something else afterwards triggers componentDidUpdate and value is still drill_free, it will again call the handleOpenDropDown() function. So you may want to protect yourself from this situation somehow.

You can check this (older) related issue, which uses componentWillReceiveProps, but you can apply same idea usingcomponentDidUpdate.

Sign up to request clarification or add additional context in comments.

1 Comment

componentDidUpdate(prevProps) { if(prevProps.selectedFastening !== this.props.selectedFastening) { this.props.selectedFastening.value === 'drill_free' && this.handleOpenDropdown() } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.