map method iteration in stepper for material ui

2019-03-05 06:02发布

问题:

  • I am trying to add the redux form inside my stepper.
  • but the problem is if I add form fields inside its reflecting in all the three places.
  • so I started debugging the stepper code.
  • found that they are iterating in map method.
  • so I thought on basis of putting if condition for label I will show the div and form tags.
  • but its not working.
  • can you tell me how to fix it.
  • so that in future I will fix it myself.
  • providing my code snippet and sandbox below

https://codesandbox.io/s/y2kjpl343z

return (
      <div className={classes.root}>
        <Stepper activeStep={activeStep} orientation="vertical">
          {steps.map((label, index) => {
            console.log("steps---->", steps);
            console.log("label---->", label);
            console.log("index---->", index);

            // if (index === 0) {
            if (label === "Select campaign settings") {
              return (
                <Step key={label}>
                  <StepLabel>{label}</StepLabel>
                  <StepContent>
                    <Typography>{getStepContent(index)}</Typography>
                    <div className={classes.actionsContainer}>
                      <div>
                        <div>test1</div>

                        <form>here</form>

                        <Button
                          disabled={activeStep === 0}
                          onClick={this.handleBack}
                          className={classes.button}
                        >
                          Back
                        </Button>
                        <Button
                          variant="contained"
                          color="primary"
                          onClick={this.handleNext}
                          className={classes.button}
                        >
                          {activeStep === steps.length - 1 ? "Finish" : "Next"}
                        </Button>
                      </div>
                    </div>
                  </StepContent>
                </Step>
              );
            }

            if (label === "Create an ad group") {
              return (
                <Step key={label}>
                  <StepLabel>{label}</StepLabel>
                  <StepContent>
                    <Typography>{getStepContent(index)}</Typography>
                    <div className={classes.actionsContainer}>
                      <div>
                        <div>test1</div>

                        <form>here</form>

                        <Button
                          disabled={activeStep === 0}
                          onClick={this.handleBack}
                          className={classes.button}
                        >
                          Back
                        </Button>
                        <Button
                          variant="contained"
                          color="primary"
                          onClick={this.handleNext}
                          className={classes.button}
                        >
                          {activeStep === steps.length - 1 ? "Finish" : "Next"}
                        </Button>
                      </div>
                    </div>
                  </StepContent>
                </Step>
              );
            }

            // return (
            //   <Step key={label}>
            //     <StepLabel>{label}</StepLabel>
            //     <StepContent>
            //       <Typography>{getStepContent(index)}</Typography>
            //       <div className={classes.actionsContainer}>
            //         <div>
            //           <div>test1</div>

            //           <form>here</form>

            //           <Button
            //             disabled={activeStep === 0}
            //             onClick={this.handleBack}
            //             className={classes.button}
            //           >
            //             Back
            //           </Button>
            //           <Button
            //             variant="contained"
            //             color="primary"
            //             onClick={this.handleNext}
            //             className={classes.button}
            //           >
            //             {activeStep === steps.length - 1 ? "Finish" : "Next"}
            //           </Button>
            //         </div>
            //       </div>
            //     </StepContent>
            //   </Step>
            // );
          })}
        </Stepper>
        {activeStep === steps.length && (
          <Paper square elevation={0} className={classes.resetContainer}>
            <Typography>All steps completed - you&apos;re finished</Typography>
            <Button onClick={this.handleReset} className={classes.button}>
              Reset
            </Button>
          </Paper>
        )}
      </div>
    );

回答1:

Here is a working codesandbox: https://codesandbox.io/s/6l3wpo3xyr

To me, it seems that is working properly and with clear code. It can be done a bit better but to start with, it may be ok.

I can edit the answer to add details if needed.

Answer for comment about Object.entries

As an instance variable for the component I declared:

steps = {
  "Select campaign settings": Step1,
  "Create an ad group": Step2,
  "Create an ad": Step3
};

This is just a Plain Javascript Object. In ES6 the Object class has the entries method that, taken an object like this one, returns an array an array of key and values of the given object. In this case:

Object.entries(steps)

[
  [ "Select campaign settings", Step1 ],
  [ "Create an ad group", Step2 ],
  [ "Create an ad", Step3 ]
]

Having such a structure, it's easier to map through the key-value pairs with map. The first argument of the map method of the Array class is the current element of the array. Having used Object.entries earlier, the element is the single array that represents a key-pair:

Object.entries(steps)[0]  // [ "Select campaign settings", Step1 ]

Answer for comment about .map(([ label, CustomStep ]) => ...

This is just a common use of the Array.map method. Generally, it allows to transform an array into another using a mapping function. A function that takes an element of the array and return another thing.

In this case, the element of the array to cycle is the key-value pair provided by the Object.entries call. With ES6 arrays, as well as objects, can be destructured, and that is what is happening there:

// you may see something like this around:
.map(element => {
  // let's say that element is an array, you'll use it like:
  // element[0] is the first element
  // element[1] is the second one
})

// with ES6 that array can be destructed on-the-fly this way, which is totally equivalent
.map(([ label, CustomStep ]) => {
  // label is the index 0 (element[0])
  // CustomStep is the index 1 (element[1])
})