如果我有这三行,如何将功能组件转换为 class 组件?
How to convert a functional component to a class component if I have these three lines?
我有 SignupForm 组件。它是功能组件。但我需要将此组件重新制作为 class 组件。
我知道 class 组件必须有:
- 行如下:
class SignupForm extends React.Component
- 方法
render()
- 在我的例子中
state
而不是useState
- 在我的例子中是方法
setState
而不是setErrorMessage(res[0].message);
但我还有:
const history = useHistory();
history.push("/home");
方法中onSubmit
const {handleSubmit, values, handleChange, errors, handleBlur, isSubmitting, setSubmitting} = useFormik({ /.. });
而且我不知道如何通过这三行将功能组件重新制作为class组件。怎么做?
小部分SignupForm.js:
const SignupForm = () => {
const history = useHistory();
const [errorMessage, setErrorMessage] = React.useState(null);
const {handleSubmit, values, handleChange, errors, handleBlur, isSubmitting, setSubmitting} = useFormik({
initialValues: {
/........
},
validateOnBlur: false,
/........
validationSchema: yup.object().shape({
username: yup.string()
.required('This field is required'),
/........
}),
onSubmit: async (formValues) => {
try {
const res = await apiFunction('api/auth/register', {
/........
});
if(Array.isArray(res)){
setErrorMessage(res[0].message);
} else {
const token = res.token.token;
localStorage.setItem('myToken', token);
history.push("/home");
}
} catch(e) {
/........
}
},
});
return (
<form onSubmit={handleSubmit}>
<SignupInput
/.......
inputProps={{
name:'username',
value: values.username,
onBlur: handleBlur,
/.......
}} error={errors.username} />
<button type="submit" disabled={isSubmitting}>Submit Form</button>
</form>
);
};
您可以围绕 class 组件创建一个函数包装器。 Thas 允许您在 wrapper 中初始化挂钩并将其传递给您的 class 组件。这是如何实现的代码片段。
function hooksWrapper(component) {
const history = useHistory();
const formikData = useFormik({ /* pass everything as in your code */ });
return props => React.createElement(component, {
...props,
history,
formikData
}, null);
};
class MyComponent extends React.Component {
render() {
const { history, formikData } = this.props;
const {
handleSubmit,
values,
handleChange,
errors,
handleBlur,
isSubmitting,
setSubmitting
} = formikData;
...
};
}
export default hooksWrapper(MyComponent);
您好,我不确定我是否正确理解了您的问题以及为什么您需要将功能组件重写为 classes。
在 classes 中你不能使用 React hooks。您可以混合 class 呈现功能等的组件。
但是如果你需要重写这个组件,你将需要 HoC(高阶 React 组件)组件。这个 HoC 组件包装你的虚拟组件并将项目(历史等)作为道具传递。
例如,useHistory 的替代方案是 HoC withRouter
https://reacttraining.com/react-router/core/api/withRouter
所以对于 formik withFormik()
https://jaredpalmer.com/formik/docs/api/withFormik
关于 HoC 的更多信息
https://reactjs.org/docs/higher-order-components.html
我有 SignupForm 组件。它是功能组件。但我需要将此组件重新制作为 class 组件。
我知道 class 组件必须有:
- 行如下:
class SignupForm extends React.Component
- 方法
render()
- 在我的例子中
state
而不是useState
- 在我的例子中是方法
setState
而不是setErrorMessage(res[0].message);
但我还有:
const history = useHistory();
history.push("/home");
方法中onSubmitconst {handleSubmit, values, handleChange, errors, handleBlur, isSubmitting, setSubmitting} = useFormik({ /.. });
而且我不知道如何通过这三行将功能组件重新制作为class组件。怎么做?
小部分SignupForm.js:
const SignupForm = () => {
const history = useHistory();
const [errorMessage, setErrorMessage] = React.useState(null);
const {handleSubmit, values, handleChange, errors, handleBlur, isSubmitting, setSubmitting} = useFormik({
initialValues: {
/........
},
validateOnBlur: false,
/........
validationSchema: yup.object().shape({
username: yup.string()
.required('This field is required'),
/........
}),
onSubmit: async (formValues) => {
try {
const res = await apiFunction('api/auth/register', {
/........
});
if(Array.isArray(res)){
setErrorMessage(res[0].message);
} else {
const token = res.token.token;
localStorage.setItem('myToken', token);
history.push("/home");
}
} catch(e) {
/........
}
},
});
return (
<form onSubmit={handleSubmit}>
<SignupInput
/.......
inputProps={{
name:'username',
value: values.username,
onBlur: handleBlur,
/.......
}} error={errors.username} />
<button type="submit" disabled={isSubmitting}>Submit Form</button>
</form>
);
};
您可以围绕 class 组件创建一个函数包装器。 Thas 允许您在 wrapper 中初始化挂钩并将其传递给您的 class 组件。这是如何实现的代码片段。
function hooksWrapper(component) {
const history = useHistory();
const formikData = useFormik({ /* pass everything as in your code */ });
return props => React.createElement(component, {
...props,
history,
formikData
}, null);
};
class MyComponent extends React.Component {
render() {
const { history, formikData } = this.props;
const {
handleSubmit,
values,
handleChange,
errors,
handleBlur,
isSubmitting,
setSubmitting
} = formikData;
...
};
}
export default hooksWrapper(MyComponent);
您好,我不确定我是否正确理解了您的问题以及为什么您需要将功能组件重写为 classes。
在 classes 中你不能使用 React hooks。您可以混合 class 呈现功能等的组件。
但是如果你需要重写这个组件,你将需要 HoC(高阶 React 组件)组件。这个 HoC 组件包装你的虚拟组件并将项目(历史等)作为道具传递。
例如,useHistory 的替代方案是 HoC withRouter https://reacttraining.com/react-router/core/api/withRouter
所以对于 formik withFormik() https://jaredpalmer.com/formik/docs/api/withFormik
关于 HoC 的更多信息 https://reactjs.org/docs/higher-order-components.html