I am trying to use the 'Stepper' react material-ui component, but I am having difficulty using it in a class fashion, rather than function as they have in their previews.
Here is what I have so far, and it does load but with some problems:
- The text that appears is 'unknown step' meaning that the function 'getStepContent' does not gets called properly
- Every time I am hitting the 'next' button, it gives me an error saying: 'Cannot read property 'has' of undefined' seems like almost all of my function calls are messed up..
Here is my code:
import React, { Component } from "react";
import "./CharacterCreate.css";
import PropTypes from 'prop-types';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import Typography from '@material-ui/core/Typography';
import Box from '@material-ui/core/Box';
import { makeStyles } from '@material-ui/core/styles';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepLabel from '@material-ui/core/StepLabel';
import Button from '@material-ui/core/Button';
export default class CharacterCreate extends Component {
constructor(props) {
super(props);
this.state = {
activeStep: 0,
skipped :new Set()
};
this.handleNext = this.handleNext.bind(this);
this.isStepSkipped = this.isStepSkipped.bind(this);
}
getSteps() {
return ['Select campaign settings', 'Create an ad group', 'Create an ad'];
}
getStepContent(step) {
switch (step) {
case 0:
return 'Select campaign settings...';
case 1:
return 'What is an ad group anyways?';
case 2:
return 'This is the bit I really care about!';
default:
return 'Unknown step';
}
}
isStepOptional(step) {
return step === 1;
}
isStepSkipped(step) {
return this.state.skipped.has(step);
}
handleNext() {
let newSkipped = this.skipped;
if (this.isStepSkipped(this.activeStep)) {
newSkipped = new Set(newSkipped.values());
newSkipped.delete(this.activeStep);
}
this.setState({activeStep: prevActiveStep => prevActiveStep + 1})
this.setState({skipped: this.skipped});
}
handleBack() {
this.setState({activeStep: prevActiveStep => prevActiveStep - 1})
}
handleSkip() {
if (!this.isStepOptional(this.activeStep)) {
// You probably want to guard against something like this,
// it should never occur unless someone's actively trying to break something.
throw new Error("You can't skip a step that isn't optional.");
}
this.setState({activeStep: prevActiveStep => prevActiveStep + 1})
this.setSkipped(prevSkipped => {
const newSkipped = new Set(prevSkipped.values());
newSkipped.add(this.activeStep);
return newSkipped;
});
}
handleReset() {
this.setState({activeStep: 0})
}
render() {
const steps = this.getSteps();
return (
<div className="root">
<Stepper activeStep={this.activeStep}>
{steps.map((label, index) => {
const stepProps = {};
const labelProps = {};
if (this.isStepOptional(index)) {
labelProps.optional = <Typography variant="caption">Optional</Typography>;
}
if (this.isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={label} {...stepProps}>
<StepLabel {...labelProps}>{label}</StepLabel>
</Step>
);
})}
</Stepper>
<div>
{this.activeStep === steps.length ? (
<div>
<Typography className="instructions">
All steps completed - you're finished
</Typography>
<Button onClick={this.handleReset} className="button">
Reset
</Button>
</div>
) : (
<div>
<Typography className="instructions">{this.getStepContent(this.activeStep)}</Typography>
<div>
<Button disabled={this.activeStep === 0} onClick={this.handleBack} className="button">
Back
</Button>
{this.isStepOptional(this.activeStep) && (
<Button
variant="contained"
color="primary"
onClick={this.handleSkip}
className="button"
>
Skip
</Button>
)}
<Button
variant="contained"
color="primary"
onClick={this.handleNext}
className="button"
>
{this.activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
)}
</div>
</div>
);
}
}
I know it's a lot, but I'm simply trying to use the same example code from material-ui website as a class instead of a function..
Thank you for your help!