๐ 6์ฅ Hooks
Hooks๋ ๋ฆฌ์กํธ 16.8 ๋ฒ์ ์ ์๋กญ๊ฒ ์ถ๊ฐ๋ ๊ธฐ๋ฅ์ ๋๋ค. Hooks๋ฅผ ์ฌ์ฉํด ์ปดํฌ๋ํธ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ฑฐ๋ ์๋ช ์ฃผ๊ธฐ์ ๋ฐ๋ผ ํน์ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
6.1 useState
useState ํจ์๋ฅผ ํธ์ถํ๋ฉด ๋ณ์์ ๊ทธ ๋ณ์๋ฅผ ์์ ํ ์ ์๋ setter ํจ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฐํํฉ๋๋ค.
const Counter = () => {
const [count, setCount] = useState(0);
return (
<>
<StyledText>count: {count}</StyledText>
<Button title="+" onPress={() => setCount(count + 1)} />
<Button title="-" onPress={() => setCount(count - 1)} />
</>
);
};
โ ์ธํฐ ํจ์
- ์ธํฐ ํจ์์ ๋ณ๊ฒฝ๋ ์ํ์ ๊ฐ์ ์ ๋ฌ
- ์ธํฐ ํจ์์ ํ๋ผ๋ฏธํฐ์ ํจ์๋ฅผ ์ ๋ฌ
๊ทธ๋ฅ ๋ณ๊ฒฝ๋ ์ํ์ ๊ฐ์ ์ ๋ฌํ๋ ๊ฒฝ์ฐ ์๋ ์ฝ๋์ setCount๊ฐ ํ ๋ฒ๋ฐ์ ์๋ํ์ง ์์ต๋๋ค.
onPress={() => {
setCount(count + 1)
setCount(count + 1)
}}
โ ์ธํฐ ํจ์๊ฐ ๋น๋๊ธฐ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ ์ธํฐ ํจ์๋ฅผ ํธ์ถํด๋ ๋ฐ๋ก ์ํ๊ฐ ๋ณ๊ฒฝ๋์ง ์๋ ๊ฒ
→ ์ธํฐ ํจ์์ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌํด์ผ ํฉ๋๋ค.
onPress={() => {
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
}}
→ setCount๊ฐ ๋ ๋ฒ ์๋ํฉ๋๋ค.
6.2 useEffect
useEffect๋ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋ ๋๋ง๋ค ์ํ๋ ์์ ์ด ์คํ๋๋๋ก ์ค์ ํ ์ ์๋ ๊ธฐ๋ฅ์ ๋๋ค.
const Form = () => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
useEffect(() => {
console.log(`name: ${name}, email: ${email}`);
});
return (
<>
<StyledText>Name: {name}</StyledText>
<StyledText>Email: {email}</StyledText>
<StyledTextInput
value={name}
onChangeText={(text) => setName(text)}
placeholder="name"
/>
<StyledTextInput
value={email}
onChangeText={(text) => setEmail(text)}
placeholder="email"
/>
</>
);
};
โ ํน์ ์กฐ๊ฑด์์ ์คํํ๊ธฐ
ํน์ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง ํธ์ถํ๊ณ ์ถ์ ๊ฒฝ์ฐ ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ ์ํ ๊ด๋ฆฌ ๋ณ์๋ฅผ ๋ฐฐ์ด๋ก ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค.
useEffect(() => {
console.log(`name: ${name}, email: ${email}`);
}, [email]);
→ email์ด ๋ณ๊ฒฝ๋ ๋๋ง useEffect๊ฐ ์คํ๋ฉ๋๋ค.
โ ๋ง์ดํธ๋ ๋ ์คํํ๊ธฐ
๋ง์ดํธ ๋ ๋ ์คํํ๋๋ก ์ค์ ํ๊ณ ์ถ์ผ๋ฉด ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ ๋น ๋ฐฐ์ด์ ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค.
useEffect(() => {
console.log(`name: ${name}, email: ${email}`);
}, []);
โ ์ธ๋ง์ดํธ๋ ๋ ์คํํ๊ธฐ
useEffect ๋ง์ง๋ง์ ๋ฆฌํด๋ฌธ์ ์ฌ์ฉํ๋ฉด ํด๋น ๊ตฌ๋ฌธ์ ์ธ๋ง์ดํธ ๋ ๋ ์คํ๋ฉ๋๋ค.
useEffect(() => {
console.log(`name: ${name}, email: ${email}`);
return () => console.log('unmount\\n');
}, []);
6.3 useRef
Javascript์์ ํน์ DOM์ ์ ํํ ๋ getElementById์ ๊ฐ์ ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ฐ์ ์ํฉ์ ๋ฆฌ์กํธ์์๋ ref๋ฅผ ์ฌ์ฉํด ์ปดํฌ๋ํธ๋ฅผ ์ ํํฉ๋๋ค.
useRef๋ ํน์ ์ปดํฌ๋ํธ๋ฅผ ์ ํํด์ผ ํ๋ ์ํฉ์์ ์ฌ์ฉํ ์ ์๋ Hook์ ๋๋ค.
const Form = () => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const refName = useRef(null);
const refEmail = useRef(null);
useEffect(() => {
console.log(`name: ${name}, email: ${email}`);
refName.current.focus();
}, []);
return (
<>
<StyledText>Name: {name}</StyledText>
<StyledText>Email: {email}</StyledText>
<StyledTextInput
value={name}
onChangeText={(text) => setName(text)}
placeholder="name"
ref={refName}
returnKeyType="next"
onSubmitEditing={() => refEmail.current.focus()}
/>
<StyledTextInput
value={email}
onChangeText={(text) => setEmail(text)}
placeholder="email"
ref={refEmail}
returnKeyType="done"
/>
</>
);
};
๋ค์๊ณผ ๊ฐ์ด ์ค์ ํด๋์ผ๋ฉด ์ฒ์ focus๊ฐ refName์ผ๋ก ํฅํ๊ณ return key๋ฅผ ๋๋ฅด๋ฉด refEmail๋ก focus๊ฐ ํฅํฉ๋๋ค.
โ ํด๋น ๋ณ์๊ฐ ์๋๋ผ ๋ณ์์ .current ํ๋กํผํฐ์ ํด๋น ๊ฐ์ ๋ด์ต๋๋ค.
6.4 useMemo
useMemo๋ ๋์ผํ ์ฐ์ฐ์ ๋ฐ๋ณต ์ํ์ ์ ๊ฑฐํด ์ฑ๋ฅ์ ์ต์ ํํฉ๋๋ค.
const getLength = (text) => {
console.log(`Target Text: ${text}`);
return text.length;
};
const list = ["javascript", "expo", "expo", "react native"];
let idx = 0;
const Length = () => {
const [text, setText] = useState(list[0]);
const [length, setLength] = useState("");
const _onPress = () => {
setLength(getLength(text));
++idx;
if (idx < list.length) setText(list[idx]);
};
return (
<>
<StyledText>Text: {text}</StyledText>
<StyledText>Lenght: {length}</StyledText>
<Button title="Get Length" onPress={_onPress} />
</>
);
};
ํด๋น ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด ๋ง์ง๋ง ๊ฐ ์ดํ์ ๋ฌธ์์ด์ ๋ณํ๊ฐ ์์์๋ getLength ํจ์๊ฐ ๊ณ์ ํธ์ถ๋ฉ๋๋ค.
const _onPress = () => {
++idx;
if (idx < list.length) setText(list[idx]);
};
const length = useMemo(() => getLength(text), [text])
→ useMemo๋ฅผ ์ฌ์ฉํด text๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง ํจ์๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
6.5 ์ปค์คํ Hooks ๋ง๋ค๊ธฐ
ํน์ API์ GET ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๋ฐ๋ Hook ํจ์๋ฅผ ๋ง๋ค์ด๋ด ์๋ค
export const useFetch = (url) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch(url);
const result = await res.json();
if (res.ok) {
setData(result);
setError(null);
} else {
throw result;
}
} catch (error) {
setError(error);
}
};
fetchData();
}, []);
return { data, error };
};
const { data, error } = useFetch(URL)
๊ฐ๋จํ๊ฒ Hook์ ๋ง๋ค๊ณ ์ฌ์ฉํ ์ ์์ต๋๋ค.
โ ๋๋ถ๋ถ์ ๋น๋๊ธฐ ์์ ํ๋ฉด์์๋ ์์ ์ด ์๋ฃ๋๊ธฐ ์ ์ ํ๋ฉด ์ ์ฒด๋ ํน์ ๋ฒํผ์ด ์ฌ์ฉํ ์ ์๋ ์ํ๊ฐ ๋ฉ๋๋ค.
→ API ์์ฒญ์ ์งํ ์ํ๋ฅผ ์ ์ ์์ด์ผ ๋น๋๊ธฐ ์์ฒญ ์์ ์ํฉ์ ๋ฐ๋ผ ํ๋ฉด ๊ตฌ์ฑ์ ๋ฌ๋ฆฌ ํ ์ ์์ต๋๋ค.
→ inProgress ์ํ ์ถ๊ฐ
export const useFetch = (url) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [inProgress, setInProgress] = useState(false);
useEffect(() => {
const fetchData = async () => {
try {
setInProgress(true);
const res = await fetch(url);
const result = await res.json();
if (res.ok) {
setData(result);
setError(null);
} else {
throw result;
}
} catch (error) {
setError(error);
} finally {
setInProgress(false);
}
};
fetchData();
}, []);
return { data, error, inProgress };
};
return (
<>
{inProgress && (
<LoadingMessage>Loading...</LoadingMessage>
)}
<StyledImage source={data?.message ? { uri: data.message } : null />
<ErrorMessage>{error?.message}</ErrorMessage>
</>
)
โ ์์ฃผ ์ฌ์ฉ๋๋ ๋ถ๋ถ์ ๋ถ๋ฆฌํด Hooks๋ก ๋ง๋ค๋ฉด ๊น๋ํ๊ฒ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
๐ 7์ฅ Context API
์ปดํฌ๋ํธ๊ฐ ์๋๋ผ ์ ์ญ์ ์ผ๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด Context API๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
7.1 ์ ์ญ ์ํ ๊ด๋ฆฌ
๋ฐ์ดํฐ๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ๋ฉ๋๋ค.
๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๊ฐ ๋ง์ ๊ฒฝ์ฐ ๊ด๋ฆฌํ๋ ์ํ๊ฐ ์ถ๊ฐ๋๊ฑฐ๋ ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ ๋ชจ๋ ๊ณผ์ ์ ์ปดํฌ๋ํธ๋ฅผ ์์ ํด์ผํ๋ค๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
→ Context API๋ฅผ ์ฌ์ฉํด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.
7.2 Context API
import { createContext } from 'react'
const UserContext = createContext({ name: "Kim" });
export default UserContext;
โ Consumer
Context ์ค๋ธ์ ํธ๋ ๊ธฐ๋ณธ๊ฐ, Consumer, Provider ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
Consumer ์ปดํฌ๋ํธ๋ ์์ ์ปดํฌ๋ํธ ์ค ๊ฐ์ฅ ๊ฐ๊น์ด ๊ณณ์ ์๋ Provider ์ปดํฌ๋ํธ๊ฐ ์ ๋ฌํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๐ก ์์ ์ปดํฌ๋ํธ ์ค Provider ์ปดํฌ๋ํธ๊ฐ ์๋ค๋ฉด createContext ํจ์์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํฉ๋๋ค.
// src/components/User.js
import React from 'react';
import styled from 'styled-components';
import UserContext from '../contexts/User';
const StyledText = styled.Text`
font-size: 24px;
margin: 10px;
`
const User = () => {
return(
<UserContext.Consumer>
{value => <StyledText>Name: {value.name}</StyledText>}
</UserContext.Consumer>
)
}
export default User;
// src/App.js
import User from './components/User'
const App = () => {
return (
<Container>
<User/>
</Container>
)
}
โ Provider
Provider ์ปดํฌ๋ํธ๋ ํ์ ์ปดํฌ๋ํธ์ Context์ ๋ณํ๋ฅผ ์๋ฆฌ๋ ์ญํ ์ ํฉ๋๋ค. value๋ฅผ ๋ฐ์์ ๋ชจ๋ ํ์ ์ปดํฌ๋ํธ์ ์ ๋ฌํ๊ณ ํ์ ์ปดํฌ๋ํธ๋ Provider ์ปดํฌ๋ํธ์ value๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๋ค์ ๋ ๋๋ง๋ฉ๋๋ค.
// src/App.js
import UserContext from './contexts/User';
const App = () => {
return (
<UserContext.Provider value={{ name: "kim" }}>
<Container>
<User/>
</Container>
</UserContext.Provider>
)
}
Provider๋ก ๊ฐ์ธ๋ฉด User ์ปดํฌ๋ํธ์์ ์ฌ์ฉ๋ Consumer ์ปดํฌ๋ํธ๋ ๋์ด์ Context์ ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ Provider์์ value๋ฅผ ์ ์ธํด์ฃผ์ด์ผ ํฉ๋๋ค.
Provider ์ปดํฌ๋ํธ๋ก๋ถํฐ value๋ฅผ ์ ๋ฌ๋ฐ๋ ํ์ ์ปดํฌ๋ํธ ์์๋ ์ ํ์ด ์์ง๋ง, Consumer ์ปดํฌ๋ํธ๋ ๊ฐ์ฅ ๊ฐ๊น์ด Provider ์ปดํฌ๋ํธ์์ ๊ฐ์ ๋ฐ์ต๋๋ค.
โ Context ์์ ํ๊ธฐ
// src/contexts/User.js
import React, { createContext, useState } from 'react';
const UserContext = createContext({
user: { name: '' },
dispatch: () => {},
});
const UserProvider = ({ children }) => {
const [name, setName] = useState("Kim");
const value = { user: { name }, dispatch: setName };
return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
}
const UserConsumer = UserContext.Consumer;
export { UserProvider, UserConsumer };
export default UserContext;
Provider ์ปดํฌ๋ํธ์ value์ ์ ์ญ์ ์ผ๋ก ๊ด๋ฆฌํ ์ํ ๋ณ์์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์๋ฅผ ํจ๊ป ์ ๋ฌํ๋ UserProvider ์ปดํฌ๋ํธ๋ฅผ ์์ฑํฉ๋๋ค.
ํด๋น UserProvider๋ ๊ธฐ์กด์ ์ปดํฌ๋ํธ์ ๋ฌ๋ฆฌ ํ์์ ์๋ Consumer ์ปดํฌ๋ํธ์ ์์ ํจ์์ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ดํฐ๋ฟ๋ง ์๋๋ผ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ํจ์ dispatch๋ ํจ๊ป ์ ๋ฌํฉ๋๋ค.
// src/App.js
import { UserProvider } from './contexts/User';
const App = () => {
return (
<UserProvider>
<Container>
<User />
</Container>
</UserProvider>
)
}
...
// src/components/User.js
import React from 'react';
import styled from 'styled-components';
import { UserConsumer } from '../contexts/User';
const User = () => {
return (
<UserConsumer>
{({ user }) => <StyledText>name: {user.name}</StyledText>}
</UserConsumer>
)
}
→ ๊ฐ๋จํ๊ฒ Provider์ Consumer๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ํ๊ฐ์ ์ฌ์ฉํ ๋ฟ๋ง ์๋๋ผ ํจ๊ป ์ ๋ฌ๋ ์ธํฐํจ์๋ฅผ ์ฌ์ฉํด ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
// src/components/Input.js
import React, { useState } from 'react';
import { UserConsumer } from '../contexts/User';
const Input = () => {
const [name, setName] = useState('');
return (
<UserConsumer>
{({ dispatch }) => {
return (
<TextInput
value={name}
onChangeText={text => setName(text)}
onSubmitEditing={() => {
dispatch(name);
setName('');
}}
autoCorrect={false}
autoCapitalize="none"
returnKeyType="done"
/>
)
}}
</UserConsumer>
)
}
export default Input;
useState๋ฅผ ์ฌ์ฉํด name์ ์ํ ๋ณ์๋ฅผ ์์ฑํ๊ณ TextInput ์ปดํฌ๋ํธ์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค name์ ๋ฐ์๋๋๋ก ํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ dispatch๋ฅผ ์ฌ์ฉํด ํค๋ณด๋์ ํ์ธ ๋ฒํผ์ ๋๋ฅด๋ฉด TextInput์ ์ปดํฌ๋ํธ์ ์ ๋ ฅ๋ ๊ฐ์ผ๋ก Context์ ๊ฐ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค.
7.3 useContext
useContext Hook์ ์ฌ์ฉํด Context๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
// src/components/User.js
import React, { useContext } from 'react';
import UserContext from '../contexts/User';
const User = () => {
const { user } = useContext(UserContext);
return <Text>name: {user.name}</Text>
}
...
// src/components/Input.js
import React, { useState, useContext } from 'react';
import UserContext from '../contexts/User';
const Input = () => {
const [name, setName] = useState('');
const { dispatch } = useContext(UserContext);
return (
<TextInput
value={name}
onChangeText={text => setName(text)}
onSubmitEditing={() => {
dispatch(name);
setName('');
}}
autoCorrect={false}
autoCapitalize="none"
returnKeyType="done"
/>
)
}
useContext๋ฅผ ์ฌ์ฉํด ํธํ๊ฒ Context๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
'3-1๊ธฐ ์คํฐ๋ > React Native' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[5์ฃผ์ฐจ] ๋ด๋น๊ฒ์ด์ (0) | 2021.11.22 |
---|---|
[3์ฃผ์ฐจ] ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ๋ก โ TODO List ๋ง๋ค๊ธฐ (0) | 2021.11.08 |
[2์ฃผ์ฐจ] 4์ฅ ์คํ์ผ๋ง (0) | 2021.11.08 |
[1์ฃผ์ฐจ] ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ์ ์ปดํฌ๋ํธ (1์ฅ~3์ฅ) (0) | 2021.10.15 |
๋๊ธ