I am new to React and have had some hard time to understand the concept of states.
Down below I export a stepper from MUI. I use state
export default function CustomizedSteppers() {
const steps = ['Zoninfo', 'Betalsätt', 'Börja ladda'];
const [activeStep, setActiveStep] = React.useState(0);
const handleNext = () => {
setActiveStep((activeStep 1));
};
return (
//...
//Stepper stuff...
//...
<Button variant="contained" onClick={handleNext}>Hello
World</Button>
</Stack>
);
}
I now want to split this code so that I can setActiveStep from another component.
Meaning, I want to put the button outside of this component and put it in another class, but still allow that button to change the value of activeStep - by accessing the method handleNext on click on a button outside this class. How do I manage to do this?
CodePudding user response:
Try understanding following code .
const Child = (props)=>{
return (
<Button variant="contained" onClick={props.handleNext}>Hello
World</Button>
)
}
const Parent = ()=>{
const steps = ['Zoninfo', 'Betalsätt', 'Börja ladda'];
const [activeStep, setActiveStep] = React.useState(0);
const handleNext = () => {
setActiveStep((activeStep 1));
};
return (
<Child handleNext={(e)=>handleNext(e)} />
)
}
Take this code as a sample example and try implementing it with your code .
What is happening in this Parent Function ?
We are passing handleNext as a prop to to Child component which triggers handleNext function inside Parent component when a button is clicked inside Child component.
CodePudding user response:
You can just pass the state updating function as a prop to your component.
Your Button Component:
function CustomButtonComponent (props) {
return (
<button onClick={() => props.setCount(count => count 1)}>
Click me
</button>
)
}
export default CustomButtonComponent
And In Your Main Component
<CustomButtonComponent setCount={setCount} />
Also Since state updates are scheduled in React, you shouldnt use
onClick={() => setCount(count 1)}
Instead use
onClick={() => setCount(prevCount => prevCount 1)}
CodePudding user response:
You need to make a parent component, define activeStep
and handleNext
there, and pass them to your CustomizedSteppers
Parent.js
import CustomizedSteppers from "./CustomizedSteppers"
export default function Parent() {
const steps = ['Zoninfo', 'Betalsätt', 'Börja ladda'];
const [activeStep, setActiveStep] = React.useState(0);
const handleNext = () => {
setActiveStep((activeStep 1));
};
return (
<>
<CustomizedSteppers activeStep={activeStep} handleNext={handleNext}>
<Button variant="contained" onClick={handleNext}>Hello
World</Button>
</>
)
}
CustomizedSteppers.js
export default function CustomizedSteppers({activeStep, handleNext}) {
return (
//...
//Stepper stuff...
//...
<Button variant="contained" onClick={handleNext}>Hello
World</Button>
</Stack>
);
}
CodePudding user response:
You have a couple options.
The first is to lift your state, like @Peter said. That is, you'll need to move activeStep to the component that houses both this component and the other component you want to have activeStep's value, and then pass that value to both (a practice known as prop drilling). This is probably the simplest way, if this is the only variable you want to do that for.
The second is to use state management tools, like @ahmetkilinc said. The Context API is native to React, so it won't require any extra installations or tools. There are also third-party tools like Redux that try to solve this problem (though I believe Redux is still just using Contexts behind the scenes, anyway). This option is better if this is a need you anticipate having multiple times throughout your application.