IOS App을 만들다가 키보드가 올라오지 않을 때?
Command + K를 눌러주면 터치바가 올러오게 된다.
영구적으로 적용시켜주려면?
Simulator에서
I/O ➡ Keyboard ➡ Connect Hardware Keyboard
이렇게 간단한데.. 이 분 블로그 아니었으면 엄청 시간 쏟을뻔 했다.
flat() 메서드는 모든 하위 배열 요소를 지정한 깊이까지 재귀적으로 이어붙인 새로운 배열을 생성한다.
const newArr = arr.flat([depth])
depth - 중첩 배열 구조를 평탄화할 때 사용할 깊이 값. 기본값은 1이다.
flat( [1, [2,3], [4,5], [6,7] ] ) ⬅ 안에 여러 배열을 합쳐 하나의 배열로 반환한다. [1,2,3,4,5,6,7]const arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(); // 기본값 1이라 하나의 배열만 병합하여 새로운 배열을 생성함
// [1, 2, 3, 4, [5, 6]]
const arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); // 2개의 배열을 하나로 병합하여 새로운 배열 생성
// [1, 2, 3, 4, 5, 6]
const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity); // infinity속성으로 모든 배열을 하나로 병합하여 새로운 배열 생성
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
flat()메서드는 배열의 공백을 제거하여 새로운 배열을 반환한다.
const arr5 = [1, 2, , 4, 5];
arr5.flat();
// [1, 2, 4, 5]
reverse()메서드는 배열의 순서를 반전시킨다. 첫 번째 요소는 마지막 요소가 되고, 마지막 요소는 첫 번째 요소가 된다.
주의 사항
reverse 메서드는 호출한 배열을 반전하고 🔥 원본 배열을 변형하며 그 참조를 반환합니다.
예시코드
const array1 = ['one', 'two', 'three'];
console.log('array1:', array1);
// expected output: "array1:" Array ["one", "two", "three"]
✅ const reversed = array1.reverse();
✅ console.log('reversed:', reversed);
✅ // expected output: "reversed:" Array ["three", "two", "one"]
🔥 // Careful: reverse is destructive -- it changes the original array.
🔥 // reverse() 메서드는 기존 배열값을 바꿔버리기 때문에 조심해야한다.
console.log('array1:', array1);
// expected output: "array1:" Array ["three", "two", "one"]으로 기존 배열이 reverse되어 바뀌어버림.
?.는 객체 내의 key에 접근할 때, 그 참조가 유효한지 아닌지 직접 명시하지 않고도 접근할 수 있는 연산자입니다.?. 앞의 평가대상이 만약 nullish (undefined OR null)일 경우, 평가를 멈추고 undefined를 반환합니다.// 옵셔널 체이닝 연산자 사용 전 코드
const students = {
kim: {
age: 20,
score: {
korean: 90,
english: 80,
math: 40
}
},
park: {
age: 20,
}
}
console.log(students.kim.score.english); // 80;
console.log(students.park.score.english); // TypeError: Cannot read properties of undefined (reading 'english')
// 옵셔널 체이닝을 쓰지않고 줄인 코드 (undefined 도출)
console.log(students.kim.score && students.park.score.english);
// 옵셔널 체이닝을 쓰지않고 줄인 코드 (작동하는 코드)
console.log(students.kim && students.park.score && students.park.score.english);
// 옵셔널 체이닝을 사용하여 줄인 코드
console.log(students.park?.score?.english);
익명함수는 함수명 대신 ⭐️ 변수명에 함수 코드를 저장하는 구현 방식이다.
익명 함수의 소스 코드는 변수값이므로 끝에 세미콜론;을 대입한다.
익명 함수는 호출시, 변수명을 함수명처럼 사용한다.
<script>
let 변수명 = function( 매개변수 )
{
실행문;
};
</script>
👇
<script>
//익명 함수 선언 및 변수에 대입
var hello = function()
{
document.write("Hello World!");
};
//익명 함수 변수명으로 호출
hello(); // 변수가 곧 함수 그 자체임. 실행 트리거인 괄호() 꼭 넣어줘야 함.
</script>
useQuery와 다르게 mutation은 데이터를 생성, 업데이트, 삭제할 때 사용된다. insert, update, deleteuseQuery는 데이터를 불러올 때(조회) 사용. === get useMutation은 React Query를 이용해 서버에 데이터 변경 작업을 요청할 때 사용된다.useMutatution 예시 코드
// 1
const savePerson = useMutation(mutationFn);
// 2
const savePerson = useMutation({
mutationFn: mutationFn
})
➡ mutationFn ???
// 1
const savePerson = useMutation((person: Iperson) => axios.post('/url', person));
// 2
const savePerson = useMutation({
mutationFn: (person: Iperson) => axios.post('/url', person)
})
mutate는 useMutation을 이용해 작성한 내용들이 실행될 수 있도록 도와주는 trigger 역할을 합니다.useMutation을 정의 해둔 뒤 이벤트가 발생되었을 때 mutate를 사용해주면 된다.예시 코드
// 출처_상단 2번째 링크 블로그
import * as React from 'react';
import { useMutation } from 'react-query';
import styled from 'styled-components';
import axios from 'axios';
interface Iperson {
id: number;
name: string;
phone: string;
age: number;
}
const Mutation = (): JSX.Element => {
const [person, setPerson] = React.useState<Iperson>({
id: 0,
name: '',
phone: '',
age: 0,
})
const savePerson = useMutation((person: Iperson) => axios.post('http://localhost:8080/savePerson', person)); // useMutate 정의
const onSavePerson = () => {
✅ savePerson.mutate(person); // 데이터 저장
}
return (
<Wrapper>
<Person.InputTable>
<tbody>
<tr>
<td>
<Person.Text>이름</Person.Text>
</td>
<td>
<input type='text' onChange={(e) => setPerson((curPerson) => {
return {
...curPerson,
name: e.target.value
}
})}/>
</td>
</tr>
<tr>
<td>
<Person.Text>전화번호</Person.Text>
</td>
<td>
<input type='text' onChange={(e) => setPerson((curPerson) => {
return {
...curPerson,
phone: e.target.value
}
})}/>
</td>
</tr>
<tr>
<td>
<Person.Text>나이</Person.Text>
</td>
<td>
<input type='number' onChange={(e) => setPerson((curPerson) => {
return {
...curPerson,
age: Number(e.target.value)
}
})}/>
</td>
</tr>
</tbody>
</Person.InputTable>
<Person.SaveButton onClick={onSavePerson}>저장</Person.SaveButton>
</Wrapper>
)
}
export default Mutation;
const Wrapper = styled.div`
max-width: 728px;
margin: 0 auto;
text-align: center;
`;
const Person = {
InputTable: styled.table`
border-spacing: 18px 0;
text-align: center;
margin: 0 auto;
`,
Text: styled.h3``,
SaveButton: styled.button`
width: 92px;
height: 32px;
border: none;
border-radius: 8px;
background-color: orange;
color: #fff;
cursor: pointer;
`
}
// 1
const savePerson = useMutation((person: Iperson) => axios.post('http://localhost:8080/savePerson', person), {
✅ onSuccess: () => { // 요청이 성공한 경우
console.log('onSuccess');
},
✅ onError: (error) => { // 요청에 에러가 발생된 경우
console.log('onError');
},
✅ onSettled: () => { // 요청이 성공하든, 에러가 발생되든 실행하고 싶은 경우
console.log('onSettled');
}
});
// 2
const savePerson = useMutation({
mutationFn: (person: Iperson) => axios.post('/savePerson', person),
onSuccess: () => { // 요청이 성공한 경우
console.log('onSuccess');
},
onError: (error) => { // 요청에 에러가 발생된 경우
console.log('onError');
},
onSettled: () => { // 요청이 성공하든, 에러가 발생되든 실행하고 싶은 경우
console.log('onSettled');
}
})
const onSavePerson = () => {
✅ savePerson.mutate(person, {
✅ onSuccess: () => { // 요청이 성공한 경우
console.log('onSuccess');
},
✅ onError: (error) => { // 요청에 에러가 발생된 경우
console.log('onError');
},
✅ onSettled: () => { // 요청이 성공하든, 에러가 발생되든 실행하고 싶은 경우
console.log('onSettled');
}
}); // 데이터 저장
}
View의 크기를 결정하는 속성은 flex와 width, height 두 가지로 나뉜다.
width, height에 숫자를 넣으면 고정 크기, %를 넣으면 화면 크기에 따른 상대적 크기를 설정할 수 있습니다.
flex는 크기를 비율로 설정하는 것 입니다.
⭐️
flex는부모 View 크기의 특정 비율만큼 차지하게 됩니다.
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<View style={styles.case1} />
<View style={styles.case2} />
<View style={styles.case3} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
}, // ✅ 전체 컨테이너. 화면 100% 비율
case1: {
flex: 1,
backgroundColor: 'red',
}, // ✅ 부모 컨테이너의 1 차지
case2: {
flex: 3,
backgroundColor: 'green',
}, // ✅ 부모 컨테이너의 3 차지
case3: {
flex: 1,
backgroundColor: 'blue',
}, // ✅ 부모 컨테이너의 1 차지.
디바이스 전체를 지금, 1 : 3 : 1의 비율로 화면을 차지하고 있음.
flex는 부모 View 크기의 특정 비율만큼 차지하게 됩니다.
컨테이너 View의 부모는 화면 전체를 뜻하게 됩니다.
스켈레톤 UI는 실제 데이터가 렌더링 되기 전에 보이게 될 화면의 윤곽을 먼저 그려주는 로딩 애니메이션이다.
"어떤 것이 보여질 것입니다 ~"라고 미리 알려주는 효과를 주어 사용자의 이탈을 방지하는 효과를 기대할 수 있음.
예시 ) 모바일 환경에서 만약 댓글같은 것을 달았을 때,
flex-direction : column-reverse
이로써 간단하게 css 속성만으로 최신순으로 볼 수 있게 되었다.