Post

๐ŸŒŒ React ์ž…๋ฌธ โ…ซ - Form

๐ŸŒŒ React ์ž…๋ฌธ โ…ซ - Form

๐Ÿ“˜ ใ€Ž์†Œํ”Œ์˜ ์ฒ˜์Œ ๋งŒ๋‚œ ๋ฆฌ์•กํŠธใ€๋ฅผ ์ฝ๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

Form์ด๋ž€?

  • Form์€ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
  • HTML์˜ Form์€ Element ๋‚ด๋ถ€์— ๊ฐ๊ฐ์˜ ์ƒํƒœ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
  • ๋ฐ˜๋ฉด React์˜ Form์€ Component ๋‚ด๋ถ€์—์„œ State๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

โœ… HTML์˜ Form

1
2
3
4
5
6
7
<form>
ย ย ย ย <label>
ย ย ย ย 	์ด๋ฆ„ :
ย ย ย ย ย ย ย ย <input type="text" name="name"/>
ย ย ย ย </label>
ย ย ย ย <button type="submit">์ œ์ถœ</button>
</form>
  • ์ƒ๊ธฐ ์ฝ”๋“œ๋Š” HTML์˜ Form์ด๋‹ค.
  • React์—์„œ๋„ ์ž‘๋™์€ ํ•˜์ง€๋งŒ Javascript ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์— ์ ‘๊ทผํ•˜๊ธฐ๋Š” ๋ถˆํŽธํ•œ ๊ตฌ์กฐ์ด๋‹ค.

โœ… React์˜ ์ œ์–ด Component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function NameForm(props) {
	const [value, setValue] = useState('');
	
	const handleChange = (event) => {
		setValue(event.target.value);
	}
	
	const handleSubmit = (event) => {
		alert('์ž…๋ ฅํ•œ ์ด๋ฆ„ : ' + value);
		event.preventDefault();
	}
	
	return (
		<form onSubmit={handleSubmit}>
			<label>
				์ด๋ฆ„ :
				<input type="text" value={value} onChange={handleChange}/>
			</label>
			<button type="submit">์ œ์ถœ</button>
		</form>
	);
}
  • ์ œ์–ด Component๋ž€ React์˜ ํ†ต์ œ๋ฅผ ๋ฐ›์œผ๋ฉฐ, ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐ ์ œ์–ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ž…๋ ฅ Form Element์ด๋‹ค.
  • ์ƒ๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ œ์–ด Component๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž…๋ ฅ ๊ฐ’์ด React Component State๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌ๋˜์–ด ์ž…๋ ฅ๊ฐ’์„ ์›ํ•˜๋Š” ๋Œ€๋กœ ์กฐ์ข…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ชจ๋“  ์•ŒํŒŒ๋ฒณ์„ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€๊ฒฝํ•ด ๊ด€๋ฆฌํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.
1
2
3
const handleChange = (event) => {
	setValue(event.target.value.toUpperCase());
}

textarea

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function RequestForm(props) {
	const [value, setValue] = useState('์š”์ฒญ์‚ฌํ•ญ์„ ์ž…๋ ฅํ•˜์„ธ์š”.');
	
	const handleChange = (event) => {
		setValue(event.target.value);
	}
	
	const handleSubmit = (event) => {
	alert('์ž…๋ ฅํ•œ ์š”์ฒญ์‚ฌํ•ญ : ' + value);
		event.preventDefault();
	}
	
	return (
		<form onSubmit={handleSubmit}>
			<label>
				์š”์ฒญ์‚ฌํ•ญ :
				<textarea value={value} onChange={handleChnage}/>
			</label>
			<button type="submit">์ œ์ถœ</button>
		</form>
	);
}
  • ์ƒ๊ธฐ ์ฝ”๋“œ๋Š”ย textarea์— ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹คย State์˜ ๊ฐ’์ด ๋ฐ”๋€Œ๊ณ , ๋ฐ”๋€” ๋•Œ๋งˆ๋‹คย textarea์˜ย value์˜ ๊ฐ’์ด ๋ฐ”๋€ ์ฑ„๋กœ ๋‹ค์‹œ ๋ Œ๋”๋ง๋œ๋‹ค.
  • ์—ฌ๊ธฐ์—์„œ๋Š”ย valueย ์„ ์–ธ ์‹œ ์ดˆ๊ธฐ ๊ฐ’์„ ๋„ฃ์–ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฒ˜์Œ ๋ Œ๋”๋ง ๋  ๋•Œ๋ถ€ํ„ฐย textarea์— ํ…์ŠคํŠธ๊ฐ€ ๋‚˜ํƒ€๋‚œ๋‹ค.

select

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function FruitSelect(props) {
	const [value, setValue] = useState('grape');
	
	const handleChange = (event) => {
		setValue(event.target.value);
	}
	
	const handleSubmit = (even) => {
		alert('์„ ํƒํ•œ ๊ณผ์ผ : ');
		event.preventDefault();
	}
	
	return (
		<form onSubmit={handleSubmit}>
			<label>
				๊ณผ์ผ์„ ์„ ํƒํ•˜์„ธ์š” :
				<select value={value} onChange={handleChange}>
					<option value="apple">์‚ฌ๊ณผ</option>
					<option value="banana">๋ฐ”๋‚˜๋‚˜</option>
					<option value="grape">ํฌ๋„</option>
					<option value="watermelon">์ˆ˜๋ฐ•</option> 
				</select>
			</label>
		</form>
	);
}
  • selectย ํƒœ๊ทธ์—์„œ ํŠน์ • ๊ฐ’์„ ์„ ํƒํ•˜๋ ค๋ฉดย valueย ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • ๋‹ค์ค‘ ์„ ํƒ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜๋ ค๋ฉดย multiple={true}๋ฅผย selectย ํƒœ๊ทธ์— ์†์„ฑ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

input file

1
<input type="file"/>
  • ์ž…๋ ฅ ๊ฐ’์ด ์ฝ๊ธฐ ์ „์šฉ์ด๋ฏ€๋กœ React์—์„œ๋Š” ๋น„์ œ์–ด Component๊ฐ€ ๋œ๋‹ค.

โœ… ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž…๋ ฅ ๋‹ค๋ฃจ๊ธฐ

1
- ํ•˜๋‚˜์˜ `Component`์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž…๋ ฅ์„ ๋‹ค๋ฃจ๋ ค๋ฉด ์—ฌ๋Ÿฌ ๊ฐœ์˜ย `State`๋ฅผ ์„ ์–ธํ•˜์—ฌ ๊ฐ๊ฐ์˜ ์ž…๋ ฅ์— ๋Œ€ํ•ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

โœ… input null value

  • ์ œ์–ด Component์—ย valueย ์†์„ฑ์„ ์ •ํ•ด์ง„ ๊ฐ’์œผ๋กœ ๋„ฃ์œผ๋ฉด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š” ํ•œ ์ž…๋ ฅ ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค.
  • ๋งŒ์•ฝย valueย ๊ฐ’์€ ๋„ฃ๋˜ ์ž์œ ๋กญ๊ฒŒ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฐ’์—ย undefinedย ๋˜๋Š”ย null์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

์‹ค์Šต

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
const [email, setEmail] = useState('');
const [name, setName] = useState('');
const [memberList, setMemberList] = useState([]); 
const [page, setPage] = useState(1);

const pageSize = 10;
const startIndex = (page - 1) * pageSize;
const currentPageData = memberList.slice(startIndex, startIndex + pageSize);

return (
    <Box>
        <Box display="flex" gap={2} sx=>
            <TextField 
                label="์ด๋ฉ”์ผ" 
                variant="outlined" 
                size="small" 
                sx=
                value={email}
                onChange={(e) => setEmail(e.target.value)} 
            />
            <TextField 
                label="์ด๋ฆ„" 
                variant="outlined" 
                size="small" 
                sx= 
                value={name}
                onChange={(e) => setName(e.target.value)}
            />
        </Box>
        <Box>
            <TableContainer component={Paper}>
                <Table sx=>
                    <TableHead>
                        <TableRow>
                            <TableCell sx=>์ด๋ฉ”์ผ</TableCell>
                            <TableCell sx=>์ด๋ฆ„</TableCell>
                            <TableCell sx=>์†Œ๊ฐœ</TableCell>
                            <TableCell sx=>์ฒ˜๋ฆฌ</TableCell>
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {currentPageData.map((member) => (
                            <TableRow key={member.id} sx=>
                                <TableCell sx=>
                                    {member.email}
                                </TableCell>
                                <TableCell sx=>
                                    {member.name}
                                </TableCell>
                                <TableCell sx=>
                                    {member.description}
                                </TableCell>
                                <TableCell sx=>
                                    {member.status === null ? (
                                        <Button
                                            variant="contained"
                                            color="primary"
                                            onClick={() => createInvitation(member)}
                                        >
                                            ์ดˆ๋Œ€
                                        </Button>
                                    ) : (
                                        member.status === 'PENDING' ? (
                                            <Button
                                                variant="contained"
                                                color="error"
                                                onClick={() => deleteInvitation(member)}
                                            >
                                                ์ทจ์†Œ
                                            </Button>
                                        ) : (
                                            member.status === 'ACCEPTED' ? '๊ฐ€์ž…์™„๋ฃŒ' : '๊ฑฐ์ ˆ' 
                                        )
                                    )}
                                </TableCell>
                            </TableRow>
                        ))}
                    </TableBody>
                </Table>
                {memberList && (
                    <Pagination
                        count={Math.ceil(memberList.length / pageSize)}
                        page={page}
                        color="primary"
                        onChange={handlePageChange}
                        sx=
                    />
                )}
            </TableContainer>
        </Box>
    </Box>
);
  • ์ฑ…์—์„œ ์ œ๊ณตํ•˜๋Š” ์‹ค์Šต ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ ํ•„์ž์˜ ํ† ์ด ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์ ธ์˜จ ์ฝ”๋“œ ์ผ๋ถ€๋ถ„์ด๋‹ค.
  • ์ž…๋ ฅ Form์— ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค State๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ค.

ํšŒ๊ณ 

  • Mui์˜ TextField Component๋ฅผ ์‚ฌ์šฉํ•œ ์‹ค์Šต ์ฝ”๋“œ์ธ๋ฐ, ๋‹ค์Œ์—๋Š” ์ง์ ‘ Component๋ฅผ ๋งŒ๋“ค์–ด ๋ด์•ผ๊ฒ ๋‹ค.
This post is licensed under CC BY 4.0 by the author.