gpt4 book ai didi

javascript - 如何在 React 中同步组件共享状态 Hook

转载 作者:行者123 更新时间:2023-12-04 08:55:17 25 4
gpt4 key购买 nike

我正在尝试使用 React 钩子(Hook)使 2 个组件与它们的父组件状态同步。
我使用水平和垂直步进器作为 Material UI 中的 2 个独立组件,它们的父类具有步进器的内容和它们的状态 应该 分享。
我使用水平和垂直步进器的原因是为了使 UI 尽可能响应。
我遇到的问题是当 activeStep根据我对组件安装生命周期的理解,由组件之一(即水平步进器)递增。调用 render 方法并且 Activestep 递增并反射(reflect)在 dom 中。但它只体现在水平步进器上。更改仅在水平步进器组件中传播。导航垂直步进器组件时,它返回最初设置为 0 的钩子(Hook)的初始状态。
我正在尝试使水平和垂直步进器与 activeStep 同步在 stepperContent 中,状态的任何变化都应该在两个组件中传播。
我的问题是
如何使它们与 activeState 同步在 stepperContent 有状态功能组件中?
steppertContent.JSX

import { makeStyles } from "@material-ui/core/styles";
import { useState, useEffect } from "react";

export const useVerticalStyles = makeStyles((theme) => ({
root: {
width: "100%",
},
button: {
marginTop: theme.spacing(1),
marginRight: theme.spacing(1),
},
actionsContainer: {
marginBottom: theme.spacing(2),
},
resetContainer: {
padding: theme.spacing(3),
},
}));

export const useHorizontalStyles = makeStyles((theme) => ({
root: {
width: "100%",
},
backButton: {
marginRight: theme.spacing(1),
},
instructions: {
marginTop: theme.spacing(1),
marginBottom: theme.spacing(1),
},
}));

export const StepperContent = () => {
const [activeStep, setActiveStep] = useState(0);

useEffect(() => {
console.log(activeStep);
}, [activeStep]);
// console.log(activeStep);

const handleNext = () => {
setActiveStep((prevActiveStep) => prevActiveStep + 1);
};

const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};

const handleReset = () => {
setActiveStep(0);
};
return { activeStep, handleNext, handleBack, handleReset };
};

export const getSteps = () => {
return [
"ACCOUNT SETUP",
"PERSONAL INFORMATION",
"CONTACT INFORMATION",
"FAMILY INFORMATION",
"SCHOOL INFORMATION",
"ADMISSION INFORMATION",
"SUBMIT INFORMATION",
];
};

export const getStepContent = (stepIndex) => {
switch (stepIndex) {
case 0:
return "CREATE YOUR ACCOUNT";
case 1:
return "What is an ad group anyways?";
case 2:
return "This is the bit I really care about!";
default:
return "Unknown stepIndex";
}
};

水平FormStepper.JSX
import React from "react";
import {
Stepper,
Step,
StepLabel,
Button,
Typography,
} from "@material-ui/core/";
import {
getStepContent,
getSteps,
useHorizontalStyles,
StepperContent,
} from "./common/stepperContent";

const HorizontalFormStepper = () => {
const classes = useHorizontalStyles();
const { activeStep, handleReset, handleBack, handleNext } = StepperContent();
const steps = getSteps();

return (
<div className={classes.root}>
<Stepper activeStep={activeStep} alternativeLabel>
{steps.map((label) => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
<div>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>
All steps completed
</Typography>
<Button onClick={handleReset}>Reset</Button>
</div>
) : (
<div>
<Typography className={classes.instructions}>
{getStepContent(activeStep)}
</Typography>
<div>
<Button
disabled={activeStep === 0}
onClick={handleBack}
className={classes.backButton}
>
Back
</Button>
<Button variant="contained" color="primary" onClick={handleNext}>
{activeStep === steps.length - 1 ? "Finish" : "Next"}
{/* {console.log(steps.length - 1)} */}
</Button>
</div>
</div>
)}
</div>
</div>
);
};

export default HorizontalFormStepper;
垂直FormStepper.JSX
import React from "react";
import {
Stepper,
Step,
StepLabel,
StepContent,
Button,
Paper,
Typography,
Grid,
Container,
} from "@material-ui/core/";
import {
getStepContent,
getSteps,
useVerticalStyles,
StepperContent,
} from "./common/stepperContent";

const VerticalFormStepper = () => {
const classes = useVerticalStyles();
const steps = getSteps();
const { activeStep, handleBack, handleNext, handleReset } = StepperContent();
return (
<Container fixed maxWidth="sm">
<Grid>
<Paper variant="outlined" elevation={2}>
<div className={classes.root}>
<Stepper activeStep={activeStep} orientation="vertical">
{steps.map((label, index) => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
<StepContent>
<Typography>{getStepContent(index)}</Typography>
<div className={classes.actionsContainer}>
<div>
<Button
disabled={activeStep === 0}
onClick={handleBack}
className={classes.button}
>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={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={handleReset} className={classes.button}>
Reset
</Button>
</Paper>
)}
</div>
</Paper>
</Grid>
</Container>
);
};

export default VerticalFormStepper;

最佳答案

另一种可能的解决方案是使用 Context API。

// StepperContent.jsx
...

export const StepperContentContext = createContext();
export const useStepperContent = () => useContext(StepperContentContext);

export const StepperContentProvider = ({ children }) => {
...

const value = { activeStep, handleNext, handleBack, handleReset };

return (
<StepperContentContext.Provider value={value}>
{children}
</StepperContentContext.Provider>
);
};
所以不要使用 StepperContent ,您现在可以使用 useStepperContent钩。
// HorizontalFormStepper.jsx
...
import {
getStepContent,
getSteps,
useHorizontalStyles,
useStepperContent
} from "./common/StepperContent";

const HorizontalFormStepper = () => {
const classes = useHorizontalStyles();
const {
activeStep,
handleReset,
handleBack,
handleNext
} = useStepperContent();
...
Edit sleepy-bell-2pgq2
可能有点矫枉过正,但它就在那里。

关于javascript - 如何在 React 中同步组件共享状态 Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63857578/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com