react-hook-form
๋ฐ material-ui
๋ก ๊ฐ๋จํ ์์์ ๋ง๋ค๋ ค๊ณ ํฉ๋๋ค. ์ ๋ ๋ค์์ ์ํํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ฃ์กํฉ๋๋ค. ์๋ชป๋ ๋ฌธ์ ๊ฒ์ ์ ๋๋ค. https://github.com/mui-org/material-ui/issues/17018 ์ ๋ณต์ ๋ณธ์ธ ๊ฒ ๊ฐ์ต๋๋ค
์ฒซ ๋ฒ์งธ ๋จ๊ณ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํฉ๋๋ค.
์ฌ์ค์ ๊ธฐ๋ฅ์ ๊ฐ์ ์ง์ฐ์ง๋ง material-ui TextField์ ์ํ๋ "์ฑ์์ง" ์ํ๋ก ์ ์ง๋๊ณ ์คํ์ผ์ด ์ง์์ง ๋ฐ์ดํฐ์ ์ผ์นํ์ง ์์ต๋๋ค.
์ด๊ธฐ ๊ฐ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ค์ ๋์ด ์๋ ์ฌ์ค์ ๊ธฐ๋ฅ์ ๊ฐ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ค์ ํ์ง๋ง ๋์์ ์ฌ์ค์ ๊ณผ ๋์ผํ๋ฉฐ(์ด ๊ฒฝ์ฐ ๋ฐ๋) ๋ฐ์ดํฐ๊ฐ ๋ก๋๋์ง๋ง TextField์ ๋ด๋ถ ์ํ๋ "์ฑ์์ง"์ด ์๋๋๋ค.
material-ui ์ ๋ ฅ์ ๋ฐ์ดํฐ๊ฐ ๋ก๋/์ญ์ ๋ ๋ ๋ด๋ถ ์ํ๋ฅผ ์๋ก ๊ณ ์ณ์ผ ํฉ๋๋ค.
์ด CodePen์์ ์ธ ๊ฐ์ง ๋ฒํผ์ ์ฌ์ฉํด ๋ณผ ์ ์์ต๋๋ค.
https://codesandbox.io/s/material-demo-ywutu
react-hook-form ํ๋ก์ ํธ์์ ๋ฌธ์ ๋ฅผ ์ ๊ธฐ ํ์ง๋ง ์์ ์๊ฐ ์ฌ๊ธฐ์์๋ ํ๋๋ฅผ ์ด๋ผ๊ณ ํด์ ์ฌ๊ธฐ์ ์์ต๋๋ค :)
waiting for users upvotes
ํ๊ทธ๋ฅผ ์ถ๊ฐํ์ต๋๋ค. ์ฌ๋๋ค์ด ๊ทธ๋ฌํ ์ง์์ ์ฐพ๊ณ ์๋์ง ํ์คํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๋ฅผ ๋ซ์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด ๋ฌธ์ ์ ์ฐฌ์ฑํ๋ฅผ ๋์ง์ญ์์ค. ์ถ์ฒ ์์ ๋ฐ๋ผ ์ฐ์ ์์๋ฅผ ์ ํฉ๋๋ค.
https://npm-stat.com/charts.html?package=formik&package=react-hook-form&package=react-final-form
๋ง์ด ํ์ํฉ๋๋ค :pray::pray::pray: ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
๋ง์ด ํ์ํฉ๋๋ค!
ํ์คํ ํ์ํฉ๋๋ค.
ํด๊ฒฐ์ฑ ์ด ๋ฌด์์ธ์ง ์ ์ ์์ต๋๊น?
๊ตฌ์ฒด์ ์ธ ๋ด์ฉ์ ์ ๋ชจ๋ฅด๊ฒ ์ง๋ง ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ชจ๋ ์ฌ์ฉํ๊ธฐ ์์ํ๋ค๋ ๊ฒ์ ์๊ณ ์์ผ๋ฉฐ ๋ ์ฌ์ด์ ๊ธด๋ฐํ ํตํฉ์ ๋ณด๊ณ ์ถ์ต๋๋ค. React Hook Form๊ณผ Material UI๋ ๊ถํฉ์ด ์ข์ต๋๋ค. TypeScript์ ๋ํ ์ง์๋ ํ๋ฅญํฉ๋๋ค.
@oliviertassinari ๋, TextField
๊ฐ ๊ธฐ๋ณธ ์
๋ ฅ์ API์์ ๋ ์ ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค! ์ ๋ง ๋ฉ์ง๋ค์. e.target.value = 'xxx'
๋ฅผ ํธ์ถํ ๋ ํ
์คํธ ์์ ์๋ฆฌ ํ์์ ํ
์คํธ ์ค๋ฒ๋ ์ด๊ฐ ์์์ต๋๋ค. ๐
https://codesandbox.io/s/react-hook-form-conditional-fields-delete-1frsm
์์ ์์์ reset
API๊ฐ ํธ์ถ๋ ํ <Switch />
๊ฐ ์ฌ์ค์ ๋์ง ์์์ต๋๋ค.
๊ธฐ๋ณธ ์์ ์ ๋ ฅ API(์ ๋ ฅ ์ฐธ์กฐ๋ฅผ ํตํด ๊ฐ ์ค์ ๋ฐ ์ฌ์ค์ )๋ฅผ ์ง์ํ๊ธฐ ์ํด ๋ชจ๋ ์์ ๊ด๋ จ ๊ตฌ์ฑ ์์๋ฅผ ๊ฐ์ง ์ ์๋ค๋ฉด ์ ๋ง ์ข์ ๊ฒ์ ๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ํฐ ์์ ์ด๊ณ react-hook-form๊ณผ ๊ฐ์ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ง์ํ๋ค๋ ๊ฒ์ ์ดํดํฉ๋๋ค. ๊ณ ๋ คํด์ผ ํ ์ฌํญ (์๋ง๋ lib๊ฐ ๋ ์ ๋ช ํด์ง ๋๊น์ง โค๏ธ)
๋ค์ ํ ๋ฒ ์ด ๋ฌธ์ ๋ฅผ ์กฐ์ฌํ๊ธฐ ์ํ ๊ทํ์ ์๊ฐ๊ณผ ๋ ธ๋ ฅ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋ํ MUI์ ํจ๊ป ์์ ํ ์ ์๋ ์์ ์ด ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค.
๊ฑด๋ฐฐ
์ฒญ๊ตฌ์
@bluebill1049 ๋ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ข์ ๊ฒฌ์ธ๋ ฅ์ ์ป๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ์ฌ์ ํ formik์ ํ์ฐธ ๋ค๋จ์ด์ ธ ์์ต๋๋ค. ์ค์์น ์ฌ์ค์ ์ด ์ ์ผํ ๋ฌธ์ ์ ๋๊น?
๋ค์ ์ด์ด ์ด ๋ฌธ์ ๋ฅผ react-hook-form
๋ ์์ง ์ด ๋ง์์ ์ ์ธ์ด๊ณ ๋ ๋ง์ ์ฌ์ฉ์๊ฐ react-hook-form
์ฑํํ๋์ง ํ์ธํ๊ธฐ ์ํด ๋ ๋ง์ ์๊ฐ์ ๊ฐ๊ณ ์ถ๋ค๋ฉด ํ๋์ด ์์ต๋๋ค. ์์ ํฉ๋ฆฌ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ ๋์ react-hook-form
์ ํธํ๋๋ ์
๋ ฅ ํ
์ด๋ธ์ ์์ ๋ฐ์ผ๋ก ์์ฑํ ๊ฒ์
๋๋ค(์ฝ๋์๋๋ฐ์ค์์๋ ๋ง์ฐฌ๊ฐ์ง์ผ ์ ์์). ์ฌ๊ธฐ์๋ ๊ฒ์ํ ๊ฒ์
๋๋ค.
react-hook-form์ด ์ ์๋ํ๊ณ ์ฌ์ฉ๋์ด ์ฆ๊ฐํ๋ฉด ๊ธฐ๋ณธ ์
๋ ฅ API(๋ค์์ ๋ฐ์ ํํฌ ์์์ด ์ฌ์ฉ๋๋ ๊ฒ)๋ก ์์
ํ๋ ๊ฒ์ ๊ณ ๋ คํ ์ ์์ต๋๋ค. input
์ ์ป๋ ๊ฒ์ด ์ข์ต๋๋ค. select
, radio
๋ฐ checkbox
๋ ์์์ ๊ธฐ๋ณธ ์ฉ๋์
๋๋ค.
์ฐธ๊ณ ๋ก @oliviertassinari ์ ๋ MUI์ react-hook-form ์ฌ์ด์ ๊ฐ๊ฒฉ์ ์ขํ ์ ์๋ ์์ ์ ํ๊ณ ์์ต๋๋ค. https://github.com/react-hook-form/react-hook-form-input
๋ํ ๊ธฐ๋ณธ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ค์ ํ๊ณ ๋ก๋ํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ์ดํด๋ณด์ญ์์ค. ๋๋ ์ ์ด๋ ์ง๊ธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ญ์์ค.
์๋ ํ์ธ์ @raikusy ์ ๊ฐ ์์ ๊ฒ์ํ ๋งํฌ๋ฅผ ์ฐธ์กฐํ์ญ์์ค. ๋์์ด ๋ ๊ฒ์ ๋๋ค. ์ฅ๊ธฐ์ ์ผ๋ก MUI ๊ตฌ์ฑ ์์๊ฐ ๊ธฐ๋ณธ ํ์ api '์ฌ์ค์ '์ ์ง์ํ๊ณ ๊ตฌ์ฑ ์์ 'ref'๋ฅผ ํตํด ๊ฐ์ ์ ๋ฐ์ดํธํ๋ ๊ฒ์ด ์ข์ง๋ง ์ด๊ฒ์ MUI์ ๋ง์ ๊ธฐ๋ฅ๊ณผ ์์ด๋์ด๊ฐ ์๋ค๊ณ ํ์ ํ๋ ํฐ ์์ ๋น์ฉ์ ๋๋ค. ์ด๋ ๊ฒ์ด ๋ ์ค์ํฉ๋๋ค. ๋ฐ์ ํํฌ ํ์์ด ์ฃผ๋ฅ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋๊ฑฐ๋ ๋์คํ๋ ๋๊น์ง ์์์ ๋ ผ์ํ ๊ฒ์ฒ๋ผ MUI๋ ์๋ฃจ์ ์กฐ์ฌ๋ฅผ ์์ํ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ด ์๋ฏธ๊ฐ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค :) ๋ฐ์ ํํฌ ์์๋ ์ฌ์ฉํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค โค๏ธ๐คฉ๐ค๐ป
์ฐธ๊ณ ๋ก ๋ํผ ๊ตฌ์ฑ ์์๋ ์ฌ์ ํ ur ์์์ด 0์ ๋ค์ ๋ ๋๋งํ ์ ์๋๋ก ํฉ๋๋ค. ์ ๋ ฅ ์ํ ์ ๋ฐ์ดํธ๋ ๋ํผ ๊ตฌ์ฑ ์์ ๋ด์์ ๊ฒฉ๋ฆฌ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.๐คฉ๐ค๐ป๐
@bluebill1049 ๊ฐ์ฌํฉ๋๋ค. ๋ณด๊ธฐ ์ข์ต๋๋ค. props์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ ์์ ํ๋๊ฐ ๊ธฐ๋ณธ๊ฐ์ ๊ฐ๋ ์กฐ๊ฑด์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด TextField ๊ตฌ์ฑ ์์๊ฐ ์์ ์๋ฃจ์ ์์๋ ์๋ํฉ๋๊น? ๋ํ ์์์ ์ํ์ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ๊ฐ์ ์ ๋ฌํ๋ ๋ ๋์ ์๋ฅผ ์ฐพ๊ณ ์์์ต๋๋ค. props๋ ํผ์ด ์ด๋ฏธ ๋ง์ดํธ๋ ํ api ํธ์ถ์์ ๋์ฌ ์ ์์ต๋๋ค.
@raikusy ๋ํผ ๊ตฌ์ฑ ์์์ ํจ๊ป reset/setValue API๋ฅผ ์ฌ์ฉํ ์ ์์ด์ผ ํฉ๋๋ค.
์ฌ์ค์ : ์ ์ฒด ์์ -> https://react-hook-form.com/api#setValue
setValue: ๊ฐ์ธ์ฉ - > https://react-hook-form.com/api#reset
RHF๋ก ์์
ํ๊ธฐ ์ํด <Slider />
์(๋ฅผ) ์ป์ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉ:
<FormControl fullWidth component="fieldset" margin="normal">
<FormLabel component="legend">Palavras</FormLabel>
<RHFInput
as={<Slider min={100} max={1200} step={100} valueLabelDisplay="auto" marks={marks} />}
type="input"
name="words"
register={register}
setValue={setValue}
/>
</FormControl>
๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
Warning: Failed prop type: Invalid prop `value` supplied to `ForwardRef(Slider)`.
in ForwardRef(Slider) (created by WithStyles(ForwardRef(Slider)))
in WithStyles(ForwardRef(Slider)) (created by SetupAccountForm)
in Unknown (created by SetupAccountForm)
in fieldset (created by ForwardRef(FormControl))
in ForwardRef(FormControl) (created by WithStyles(ForwardRef(FormControl)))
in WithStyles(ForwardRef(FormControl)) (created by SetupAccountForm)
in form (created by SetupAccountForm)
in SetupAccountForm (created by SetupAccountPage)
in div (created by ForwardRef(CardContent))
in ForwardRef(CardContent) (created by WithStyles(ForwardRef(CardContent)))
in WithStyles(ForwardRef(CardContent)) (created by SetupAccountPage)
in div (created by ForwardRef(Paper))
in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
in WithStyles(ForwardRef(Paper)) (created by ForwardRef(Card))
in ForwardRef(Card) (created by WithStyles(ForwardRef(Card)))
in WithStyles(ForwardRef(Card)) (created by SetupAccountPage)
in div (created by ForwardRef(Grid))
in ForwardRef(Grid) (created by WithStyles(ForwardRef(Grid)))
in WithStyles(ForwardRef(Grid)) (created by Layout)
in Layout (created by SetupAccountPage)
in SetupAccountPage (created by App)
in Route (created by App)
in Switch (created by App)
in Router (created by HashRouter)
in HashRouter (created by App)
in App (created by Root)
in div (created by ForwardRef(Container))
in ForwardRef(Container) (created by WithStyles(ForwardRef(Container)))
in WithStyles(ForwardRef(Container)) (created by Root)
in div (created by Styled(MuiBox))
in Styled(MuiBox) (created by Root)
in Provider (created by Root)
in Root Button.js:233:15
@hbarcelos ์ฌ๋ผ์ด๋ ๊ฐ์ ์ธ๋ชจ ๊ฐ ์ํ์ ์ง์ํ์ง ์์ต๋๋ค :( ๋๋ ๊ฑฐ๊ธฐ์ ๋ช ๊ฐ์ง ์กฐ์ฌ๋ฅผ ํ ๊ฒ์
๋๋ค. ๊ทธ ๋์, ๋น์ ์์ ๋ฑ๋ก๋๋ ๋ฑ๋ก ์ฌ์ฉ์ ์ ์ ์ฌ์ฉ ํ ์ ์์ต๋๋ค useEffect
๊ฐ์ฌํฉ๋๋ค @bluebill1049
๋๋ ๊ฒฐ๊ตญ ๋ค์๊ณผ ๊ฐ์ด ๋ง๋ค์์ต๋๋ค.
import React, { useEffect, useCallback, useState, useMemo } from 'react';
import t from 'prop-types';
import clsx from 'clsx';
import { makeStyles } from '@material-ui/core/styles';
import Box from '@material-ui/core/Box';
import Slider from '@material-ui/core/Slider';
const useStyles = makeStyles(theme => ({
sliderWrapper: {},
sliderLabel: {
marginTop: theme.spacing(1),
marginBottom: theme.spacing(0.5),
color: theme.palette.primary.main,
},
}));
function CustomSlider({
register,
unregister,
setValue,
name,
rules,
defaultValue,
valueLabelAs,
formatLabel,
...rest
}) {
const cl = useStyles();
const [currentValue, setCurrentValue] = useState(defaultValue);
useEffect(() => {
register({ name });
return () => unregister(name);
}, [defaultValue, name, register, setValue, unregister]);
const valueLabel = useMemo(() => {
if (!valueLabelAs) {
return null;
}
return React.cloneElement(
valueLabelAs,
{ className: clsx(valueLabelAs.props.className, cl.sliderLabel) },
formatLabel(currentValue)
);
}, [cl.sliderLabel, currentValue, formatLabel, valueLabelAs]);
const handleChange = useCallback(
(_, value) => {
setValue(name, value);
setCurrentValue(value);
},
[name, setValue]
);
return (
<React.Fragment>
{valueLabel}
<Box className={cl.sliderWrapper}>
<Slider {...rest} onChange={handleChange} defaultValue={defaultValue} />
</Box>
</React.Fragment>
);
}
CustomSlider.defaultProps = {
rules: {},
defaultValue: '',
valueLabelAs: null,
formatLabel: v => v,
};
CustomSlider.propTypes = {
register: t.func.isRequired,
unregister: t.func.isRequired,
setValue: t.func.isRequired,
name: t.string.isRequired,
rules: t.object,
defaultValue: t.oneOfType([t.number, t.string]),
valueLabelAs: t.node,
formatLabel: t.func,
};
export default CustomSlider;
์์๋๋ก ์๋ํฉ๋๋ค.
์ด๊ฒ๋ ๋ง์ด ํ์ํ๋ค
์ฅ๊ธฐ์ ์ผ๋ก MUI ๊ตฌ์ฑ ์์๊ฐ ๊ธฐ๋ณธ ์์ API '์ฌ์ค์ '์ ์ง์ํ๊ณ ๊ตฌ์ฑ ์์ 'ref'๋ฅผ ํตํด ๊ฐ์ ์ ๋ฐ์ดํธํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
@bluebill1049 ์ด๊ฑด React๋ react-hook-form ์์ฒด์ ๋ฌธ์ ์๋๊ฐ์? ๊ฐ๋ฐ์๋ react-hook-form์ ์ฌ์ฉํ์ฌ ์
๋ ฅ ์ํ ๋ณ๊ฒฝ์ "๋ฐ์"ํด์ผ ํฉ๋๊น?
๋ด๊ฐ ์ฌ์ฉ์ ์ ์ ์
๋ ฅ์ ๊ตฌ์ถํ๋ React ๊ฐ๋ฐ์์ด๊ณ ์์๊ฐ ์ฑ์์ง๊ฑฐ๋ ๋น์ด ์์ ๋ ๋ค๋ฅด๊ฒ ์คํ์ผ์ ์ง์ ํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด๊ฒ์ ์ด๋ป๊ฒ ๊ตฌํํด์ผ ํฉ๋๊น? ๋ณ๊ฒฝ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ React์ ์ ์ธ์ ๋ชจ๋ธ "์ธ๋ถ์์" ์ ๋ ฅ ๊ฐ์ ๋ณ๊ฒฝํ ๋ ๋ณ๊ฒฝ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๋ ๊ฒ์ ๊ณ ๋ คํด ๋ณด์ จ์ต๋๊น? @test-library/react ์์ ์ํ ๋๋
์ด๋ ๊ฒ ํ๋ฉด ๊ธฐ๋ณธ ์ ๋ ฅ ์์์ ์์กดํ๋ Material-UI ๊ตฌ์ฑ ์์๋ฅผ ์ง์ํ ์ ์์ผ๋ฉฐ Slider์ ๊ฐ์ ๋ค๋ฅธ ๊ตฌ์ฑ ์์์ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์ ์ ๋ํผ๊ฐ ์ฌ์ ํ ํ์ํฉ๋๋ค. ์ฌ๋ผ์ด๋์๋ ๊ฐ ์ํ์ด ์์ง๋ง onChange์ ์๋ช ์ ๊ธฐ๋ณธ ์ ๋ ฅ๊ณผ ๋ค๋ฆ ๋๋ค. ๋ค๋ฅธ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ #15585์ ๋ง์ฐฌ๊ฐ์ง๋ก ํตํฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ณด๋ ๊ฒ์ด ์ข์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ด ๋ฌธ์ ๊ฐ ์ ๊ทธ๋ ๊ฒ ๋ง์ ์ฐฌ์ฑ์ ์ป์๋์ง ๊ถ๊ธํ๋๋ฐ, ์๊ฒ ๋ ๊ฒ ๊ฐ์์ ๐:
https://react-hook-form.com/advanced-usage#ControlledmixedwithUncontrolledComponents
@oliviertassinari , ์ด ๋ฌธ์ ์ ๋ํด ๋ค์ ํ ๋ฒ ์์ธํ ์ดํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค ๐
๋ด๊ฐ ์ฌ์ฉ์ ์ ์ ์ ๋ ฅ์ ๊ตฌ์ถํ๋ React ๊ฐ๋ฐ์์ด๊ณ ์์๊ฐ ์ฑ์์ง๊ฑฐ๋ ๋น์ด ์์ ๋ ๋ค๋ฅด๊ฒ ์คํ์ผ์ ์ง์ ํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด๊ฒ์ ์ด๋ป๊ฒ ๊ตฌํํด์ผ ํฉ๋๊น? ๋ณ๊ฒฝ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ธฐ๋ณธ ์
๋ ฅ์ ์ฌ์ฉํ๋ ๋ด ํ๋ก์ ํธ์ ์๋ฃจ์
์ ๋ํ CSS ์ ํ๊ธฐ๋ฅผ ์ฐพ์ ๊ฒ์
๋๋ค. ์: ์์ ์ ํ์ ๋น ๊ฐ์ด ์๊ณ ์คํ์ผ ํ์. ๋์์ผ๋ก react-hook-form watch
API๋ฅผ ์ฌ์ฉํ์ฌ ๋น ๊ฐ์ ๊ฐ์งํ๊ณ prop
(๋ด ๋ํ๋ ์
๋ ฅ ๊ตฌ์ฑ ์์ ํฌํจ)๋ก ์ ๋ฌํฉ๋๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ React์ ์ ์ธ์ ๋ชจ๋ธ "์ธ๋ถ์์" ์ ๋ ฅ ๊ฐ์ ๋ณ๊ฒฝํ ๋ ๋ณ๊ฒฝ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๋ ๊ฒ์ ๊ณ ๋ คํด ๋ณด์ จ์ต๋๊น? @test-library/react์์ ์ํ๋๋ ๊ฒ์ฒ๋ผ?
์, ์ฐ๋ฆฌ๋ react-hook-form-input
์๋์์ ๊ฝค ๋ง์ด ํ๊ณ ์์ต๋๋ค. ๐
์ ๋ ์๋ ๋์ ์์์ ์ ์ดํ ํ์ ์์์ ์์ฑํ๊ธฐ ์ํ ์ ์ด๋์ง ์๋ ๊ตฌ์ฑ ์์๋ฅผ ๋ฏฟ์ต๋๋ค. ์ค์ ๋ก๋ ํจ์ฌ ๋ ์ฝ๊ฒ ์์ ์ ์ํํ ์ ์์ต๋๋ค. (Facebook LOL์์ ์ผํ๋ ๊ฒฝ์ฐ) ๋ชจ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์๋ ์์ง๋ง ์์์ ์์ฑํ ๋ ๋ด ์ง์ฅ ์ํ๊ณผ ์ฃผ๋ณ ์ฌ๋๋ค์ ๋ ์ฝ๊ฒ ๋ง๋ญ๋๋ค. HTML ์ ๋ ฅ์ ์์ฒด์ ์ผ๋ก ์ํ๋ฅผ ์ ์งํ๋ฉฐ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ด๋ฅผ ์์ฉํ๊ณ ์ถ์ต๋๋ค(์ณ๊ณ ๊ทธ๋ฆ์ ๋งํ๋ ๊ฒ์ด ์๋๋ผ ๋์ฒด ์๋ฃจ์ ).
์ ๋ React ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๋ ๊ฒ์ ๋งค์ฐ ์ข์ํฉ๋๋ค. ๊ทธ๋์ ์ฃผ๋ณ์ ๋ง์ ํจํค์ง๋ฅผ ๊ตฌ์ถํ๋ ๊ฒ์
๋๋ค. ๋๋ React๊ฐ ์ ์ด๋ ๊ตฌ์ฑ ์์๋ฅผ ์์ฉํ๋ ๊ฒ์ ์ดํดํฉ๋๋ค. ๊ทธ๋ฌ๋ react-hook-form ์ register
์์ useEffect
register
์ฌ์ฉ์ ์ ์๋ฅผ ๊ณ์ ์ํํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๊ฐ ์ ์ด๋๋ ์์์ ๋น๋ํ๋ ๊ฒ์ ์ฐจ๋จํ์ง ์์ต๋๋ค.
๊ฒฐ๋ก :
์ด ๋ฌธ์ ๋ฅผ ์ข
๋ฃํ ์ ์์ผ๋ฉฐ ์ด ๋ฌธ์ ์ ๊ด๋ จ๋ ๋ด ์น์ฌ์ดํธ์ ๋งํฌ๋ฅผ ์ ๊ฑฐํ๊ฒ ์ต๋๋ค. ๊ฒ๋ค๊ฐ react-hook-form-input
๋ฅผ ํฌํจํ๋๋ก ์ด ํ์ด์ง๋ฅผ ์
๋ฐ์ดํธํ ์ ์์ต๋๊น?
https://material-ui.com/components/text-fields/#complementary -projects
์, ์ฐ๋ฆฌ๋ react-hook-form-input์์ ๊ฑฐ์ ํ๊ณ ์์ต๋๋ค.
@bluebill1049 ๋ด ์ ์๊ณผ ๋ฐ๋๋๋ ์ ๊ทผ ๋ฐฉ์์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. ๋ค์ ์ฌํญ์ ์ดํดํฉ๋๋ค.
input.value = 'x'
ํฉ๋๋ค. ์ด๊ฒ์ ์
๋ ฅ ๊ฐ์ด ๋ณ๊ฒฝ๋์์์ ์ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ์ React์์ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ณ๊ฒฝ ์ด๋ฒคํธ๊ฐ ํธ๋ฆฌ๊ฑฐ๋์ง ์์ต๋๋ค .1. React๊ฐ react-hook-form ์ ๊ทผ ๋ฐฉ์์ ์ง์ํ๊ธฐ ์ํด ํ๋ฅญํ๊ฒ ์๋ํ ๊ฐ๋ฅ์ฑ์ ๋งค์ฐ ๋ฎ๊ณ 2. react-hook-form์ด ์ ์ด ๋ฐ ์์ฌ ์ ์ด๋์ง ์์ ์ ๋ ฅ( ๊ธฐ๋ณธ๊ฐ๊ณผ onChange๋ง ์์ ํ๋ ๊ฐ), ๋ค์๊ณผ ๊ฐ์ด ์ ์ํฉ๋๋ค.
@oliviertassinari ์์ธํ ๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค. ์ ์๋ ์๋ฃจ์ ์ผ๋ก ์ถ๊ฐ ์กฐ์ฌ๋ฅผ ์ํํ๊ฒ ์ต๋๋ค. :)
์์์ ์ธ๊ธํ React ๋ฌธ์ ์ ๋๋ถ๋ถ์ ๋ด๊ฐ ๊ฐ์ ํ๊ณ ์ถ์ ๋ถ๋ถ์ธ ์ ์ด๋ ๊ตฌ์ฑ ์์๋ฅผ ์ ํํ ๋๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋ช ํํํ๊ธฐ ์ํด :
๋ฐ๋ผ์ ๋ฐ์ ํํฌ ํ์์ผ๋ก ํด๊ฒฐํ ์ ์๋ค๊ณ ํ์ ํฉ๋๋ค. ์ด๋ฌํ ์์ ์ฌํญ์ ์๋/๋ฐฐํฌํ๊ณ ๋ฌธ์์์ ์ฐ๋ฆฌ ์ธก์ ์ฑ ์์ ์ ๊ฑฐํ ์ ์๋ค๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋งค๋ ฅ์ ๋์ด๋ ๋ฐ ์ ๋ง ๋์์ด ๋ ๊ฒ์ ๋๋ค. ๊ฐ์ฌํฉ๋๋ค. D.
์์์ ์ธ๊ธํ React ๋ฌธ์ ์ ๋๋ถ๋ถ์ ์ ์ด๋์ง ์๋ ๊ตฌ์ฑ ์์์์ ๊ฐ์ ํ๊ณ ์ถ์ ๋ถ๋ถ์ธ ์ ์ด ๋๋ ์ ์ด๋๋ ๊ตฌ์ฑ ์์๋ก ์ ํํ ๋ ๋ฐ์ํฉ๋๋ค.
React๋ ์ฌ์ฉ์๊ฐ ์ ์ด๋์ง ์์๊ณผ ์ ์ด๋จ ์ฌ์ด๋ฅผ ์ ํํ ๋ ๊ฒฝ๊ณ ํฉ๋๋ค. ๋๋ ๋น์ ์ ์์ ์ ์ดํดํ์ง ๋ชปํฉ๋๋ค.
๋ฐ๋ผ์ ๋ฐ์ ํํฌ ํ์์ผ๋ก ํด๊ฒฐํ ์ ์๋ค๊ณ ํ์ ํฉ๋๋ค. ์ด๋ฌํ ์์ ์ฌํญ์ ์๋/๋ฐฐํฌํ๊ณ ๋ฌธ์์์ ์ฐ๋ฆฌ ์ธก์ ์ฑ ์์ ์ ๊ฑฐํ ์ ์๋ค๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
๋๋ MUI๋ฅผ ๋น๋ํ๋ ๊ฒ์ด ์๋๋๋ค. ์์๋ค์ํผ, react-hook-form์ ์ด ๋ง์์ ์๋ก์ด ์๋ ์ ๋๋ค. ์ ๋ ํน์ ๋ฌธ์ ์ ๋ํ ๊ด์ฌ์ด๋ ์ถ์ง๋ ฅ์ ์ป์ผ๋ ค๊ณ ํ์ต๋๋ค. ๊ทธ๋ ๊ฒ ๋ณด์ด์ จ๋ค๋ฉด ์ฃ์กํฉ๋๋ค(๋น๋). ๋ค์ ํ ๋ฒ ๊ทํ์ ๋์๊ณผ ์กฐ์ฌ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
(๋น๋์ด ์๋)
์์์ ์ธ๊ธํ React ๋ฌธ์ ์ ๋๋ถ๋ถ์ ์ ์ด๋์ง ์๋ ๊ตฌ์ฑ ์์์์ ๊ฐ์ ํ๊ณ ์ถ์ ๋ถ๋ถ์ธ ์ ์ด ๋๋ ์ ์ด๋๋ ๊ตฌ์ฑ ์์๋ก ์ ํํ ๋ ๋ฐ์ํฉ๋๋ค.
React๋ ์ฌ์ฉ์๊ฐ ์ ์ด๋์ง ์์๊ณผ ์ ์ด๋จ ์ฌ์ด๋ฅผ ์ ํํ ๋ ๊ฒฝ๊ณ ํฉ๋๋ค. ๋๋ ๋น์ ์ ์์ ์ ์ดํดํ์ง ๋ชปํฉ๋๋ค.
์ฃ์กํฉ๋๋ค ์ ์ด ๊ตฌ์ฑ ์์๋ฅผ ์๋ฏธํ์ต๋๋ค :) ๋ด ์๊ฒฌ์ ์์ ํ์ต๋๋ค.
@bluebill1049 ๊ต์ฅ
๊ณ ๋ง์, @oliviertassinari (๋น์ ์ ๋งค์ฐ ์น์ ํฉ๋๋ค)
Material-UI๋ ์ ์๋ ๋์ผํ ์์ ์ฌํญ์ ์ ์ฉํ ์ ์์ง๋ง ์ฐ๋ฆฌ๋ ๊ทธ๋ ๊ฒ ํด์ผ ํ๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ๋ ๊ฐ์ง ๋จ์ ์ด ์์ต๋๋ค. 1. Material-UI์์๋ง ์๋ํ๋ฉฐ ๋์ผํ ๋ ธ๋ ฅ์ ๊ณ์ํด์ ์ํํด์ผ ํฉ๋๋ค. 2. ์ด๋ฌํ "ํดํน"์ ์์ ๊ถ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ทจํ ํธ๋ ์ด๋์คํ(๊ด์ฉ์ ์ธ React API ์ฐํ)์์ ๋น๋กฏ๋ ๊ฒ์ฒ๋ผ ๋ฐ์ ํํฌ ํ์์ผ๋ก ์ ์ง๋์ด์ผ ํฉ๋๋ค.
์ฌ๋ฌ๋ถ, ๋๊ตฐ๊ฐ ์ด ๋ฌธ์ ์ ๊ฐ์ ํ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ. (์ ์ ๋์ ๋น๋ฐ๋ฆฌ์ ์์ ํ์ต๋๋ค ๐)
์ฐ๋ฆฌ๋ ํนํ ์ ์ด๋๋ ๊ตฌ์ฑ ์์๋ฅผ ์ค์ฌ์ผ๋ก ์ผ๋ถ ์ถ์ ์ง ์
๋ฐ์ดํธ๊ฐ ์๋ RHF์ ๋ค์ ์ฃผ์ ๋ฒ์ ์ ์์
ํ๊ณ ์์ต๋๋ค. UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ์ง์์ด ๊ฐ์ ๋ ๊ฒ์
๋๋ค. ๋ค์ ์ฝ๋๋ ์ ์ด๋ UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํด setValue
๋ฐ defaultValue
๋ฅผ ํด๊ฒฐํ๋ ๋์์ ์ฑ/์์ ์์ค์์ ์ต์ ๋ค์ ๋ ๋๋ง์ ์ ์งํ๊ณ ์
๋ ฅ ๊ตฌ์ฑ ์์ ์์ค์์ ๋ค์ ๋ ๋๋ง์ด ๊ฒฉ๋ฆฌ๋ฉ๋๋ค.
๋ค์์ RHF์ V4๋ฅผ ์ฌ์ฉํ ๋์ ๊ตฌ๋ฌธ์ ๋๋ค.
import TextField from '@material-ui/core/TextField';
const { control } = useForm();
<Controller as={TextField} control={control} name="firstName" rules={{ required: true }} />
๋์์ด ํ์ํ๋ค.
์ฌ๋ฃ์ ํ
์คํธ ํ๋์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค(์๋ง๋ ๋ค๋ฅธ mui๋ ๋ง์ฐฌ๊ฐ์ง์).
ํ
์คํธ ํ๋๊ฐ ๋น์ด ์์ผ๋ฉด ์ฒซ ๋ฒ์งธ ํค ์ ์ฅ์๊ฐ ๋๋ฆฌ๊ณ ๊ฐ์ ๋น์ด ์๋ ๊ฒ์ผ๋ก ๋ณ๊ฒฝํ ๋๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค.
์ด๋ค ์ด์ ๋ก ์ ์ฒด ์์์ ๋ค์ ๋ ๋๋งํฉ๋๋ค.
๋น ๋ฅธ ์ฐธ๊ณ ์ฌํญ : ์ง์ฒด ์์ด ๋น ๋ฅด๊ฒ ์ ๋ ฅํ๊ณ ์์ต๋๋ค. ์ง์ฐ ๋ถ๋ถ์ ์์์ ์ธ๊ธํ ์ด์ ๋๋ฌธ์ ๋๋ค.
์๋
ํ์ธ์ ์ฌ๋ฌ๋ถ, ์ด ๋ฌธ์ ๋ react-hook-form์์ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฌ์ฉํ๋๋ผ๋ ๊ณ์ ๋ฐ์ํฉ๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ๋ค์ ์ด ์ ์์ต๋๊น? ์๋๋ฉด ๋ด๊ฐ ์๋ชปํ๊ณ ์์ต๋๊น?
์: https://codesandbox.io/s/example-muitextfield-setvalue-with-react-hook-form-kqwq0?file=/index.js
ํธ์ง: ๋ด๊ฐ ์ฌ์ฉํ๋ ์๋ฃจ์
์ InputLabelProps={isEdition && { shrink: isEdition }}
์ฌ๊ธฐ์ isEdition
๋ ํธ์ง ํ๋ฉด์์ ์ฌ์ฉํ๋ ํ๋๊ทธ์
๋๋ค.
@Luccasoli plz๋ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ญ์์ค: https://react-hook-form.com/api#Controller
MUI ์์ ๊ฐ ์๋ ์์ ๊ฐ ์์ต๋๋ค. https://codesandbox.io/s/react-hook-form-controller-079xx
์ฃ์กํฉ๋๋ค @bluebill1049 , ํ์ง๋ง ์ด ์์ ์์ ๋น์ทํ ์ํฉ์ ์ฐพ์ง ๋ชปํ๊ณ ๋ฌธ์์์ ์ด ๋ฌธ์ ๋ฅผ ์ ๋๋ก ํด๊ฒฐํ ์ ์๋ ์ํ์ ์ฐพ์ ์ ์์์ต๋๋ค.(
@Luccasoli defaultValue
๋ณด์ธ์.
๋๋ ์๋ํ๋ค:
๋ ๊ฐ์ง ๋ฐฉ๋ฒ ๋ชจ๋, textField๋ ์ ๋ ฅ์ด ์ฑ์์ง ๊ฒ์ ์ธ์ํ์ง ๋ชปํ๊ณ ๋ ์ด๋ธ์ด ์ ๋ ฅ ์์ ์ ์ง๋ฉ๋๋ค.
์, ํ์ง๋ง ์ด์ํ๊ฒ๋ defaultValue๋ฅผ ๊ทธ๋๋ก ์ ์งํฉ๋๋ค. ์ฌ์ฉ์์๊ฒ ์ด์ํ ๊ฐ์ ํ์ํ์ง ์๊ธฐ ์ํด ํญ์ ๋น ๋ฌธ์์ด ๊ฐ์ผ๋ก ์์ํ๋ ค๊ณ ํฉ๋๋ค.
"Loading" defaultValue๋ฅผ ํ์ํ ์๋ ์์ง๋ง ๋น ์ด๊ธฐ ๊ฐ์ด ์ฌ์ ํ ๋ ํฅ๋ฏธ๋กญ๊ฒ ๋ณด์ ๋๋ค. ๊ฐ๋ฅํ๋ค๊ณ ์๊ฐํ์ญ๋๊น?
ํธ์ง: ์, ๋น ๋ฌธ์์ด์์๋ ์๋ํฉ๋๋ค... ํํํ, ๊ฐ์ฌํฉ๋๋ค. ์ ์ ์๋ํ ์ ์ด ์๋ค๊ณ ๋งน์ธํ์ง๋ง ๊ทธ๋ฐ ๊ฒ ๊ฐ์ต๋๋ค.
@bluebill1049 ๋ด๊ฐ ๋ณด๊ณ ์๋ ๋ฌธ์ ๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ๋ฐ๋ชจ๋ฅผ ์กฐ์ ํ์ผ๋ฉฐ ์ข์ ์๋ฃจ์
์ด ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
https://codesandbox.io/s/react-hook-form-controller-n196b?file=/src/index.js
๋ฒํผ์ ํ์ฑํํ๊ธฐ ์ ์ ํ์ธ๋์ ์ ํจ์ฑ์ ๊ฒ์ฌํ๋ ค๊ณ ์๋ํ๋ ๊ฒ์ด ์ ํ๋ฉ๋๋ค. ๋ด๊ฐ ์ฌ์ฉํ ๋ค๋ฅธ ๋ชจ๋ ํ๋๋ ํ์ธ๋์ ์ ์ธํ๊ณ ์์๋๋ก ์๋ํฉ๋๋ค.
์ด ์๋ ๋ฐ์ค๊ฐ Material UI์ ์ ๋ง ์ ์ฉํ๋ค๋ ๊ฒ์ ์์์ต๋๋ค. ์ฌ๋ผ์ด๋, Select ๋ฐ ๊ธฐํ ๋ช ๊ฐ์ง์ ๋ํ ์์ ๊ฐ ์์ต๋๋ค.
https://codesandbox.io/s/react-hook-form-controller-079xx?file=/src/index.js
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
waiting for users upvotes
ํ๊ทธ๋ฅผ ์ถ๊ฐํ์ต๋๋ค. ์ฌ๋๋ค์ด ๊ทธ๋ฌํ ์ง์์ ์ฐพ๊ณ ์๋์ง ํ์คํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๋ฅผ ๋ซ์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด ๋ฌธ์ ์ ์ฐฌ์ฑํ๋ฅผ ๋์ง์ญ์์ค. ์ถ์ฒ ์์ ๋ฐ๋ผ ์ฐ์ ์์๋ฅผ ์ ํฉ๋๋ค.https://npm-stat.com/charts.html?package=formik&package=react-hook-form&package=react-final-form