#오늘 배운것
★리액트네이티브 공식문서에서 단어 한번 쳐보기!!!
expo 화면 새로고침하기 = 터미널 expo start후 밑의 명령어 모음에 "Press r"이 있다. 그럼 터미널을 활성화 한 상태에서 R을 누르면 새로고침이 된다.
웹의 경우 마우스로 누르는것을 고려해야하는데 앱의 경우 완료 , enter버튼누르면 적용되기 때문에 그것만 고려하면 된다. 그것이 onSubmitEditing입니다.
리액트 네이티브는 html의 div같은 기본적인 태그를 가져오는데도 import를 해야한다.또한 기본적으로 flexbox가 디폴트 값이다!!!!! display:flex 안써도 됨. 그리고 모바일에서는 기본 flex derction이 column형태다.기본이 위 > 아래
status bar = 아이폰의 시간이나 wifi상태를 보여주는 태그.안드로이드는 안보임...
JSON Formatter & Validator
Format and validate JSON data so that it can easily be read by human beings.
jsonformatter.curiousconcept.com
.map을 썼으면 key값을 쓸것..까먹지 말자...
자동완성이 안되어있으면 import가 안되어 있는 것....
yarn add @react-native-async-storage/async-storage
//
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function App() {
//add Todo : input창에서 enter누르면 todo가 추가된다.
const [todos, setTodos] = useState([]);
const [category, setCategory] = useState(""); //js,react,ct 초기값을 주면 리로드 됐을 때 ui적으로 좋지 않아서 빈배열로 쓰는게 좋을것같다...
const [text, setText] = useState("");
const [editText, setEditText] = useState("");
//setCategory : 탭별로 다른 todo 보이기(bg에 삼항연산자 주기)
//react에서는 filter를 따로 줬지만 여기서는 조건문으로 filter를 한다.
//style 조건문을 할때는 style={{ ...styles.HeaderButton,backgroundColor: category === "js" ? "#ffff00" : "#ffaa00", }}이런 형식으로 한다.
//todos와 category별개로 저장해야한다.
//isDone,완료 토글링
const setDone = (id) => {
//id를 매개변수로 받아 -> id의 해당 요소를 찾는다. -> 그 배열 요소 isDone값을 토글링한 후 setTodos한다.
const newTodos = [...todos];//얕은 복사
const idx = newTodos.findIndex(todo => todo.id === id);//id에 해당하는 idx찾기.todo에서 매개변수로 받은 id랑 같으면!
newTodos[idx].isDone = !newTodos[idx].isDone;//찾은 인덱스를 토글링 !
setTodos(newTodos);
};
//코드 치기 전 체계적으로 생각해라....
const newTodo = {
id: Date.now(), //현재 시간을 숫자로 표현한 id
text,
isDone: false,
isEdit: false, //수정값
category, //카테고리 어디에 해당하는지..
};
const addTodo = () => {
setTodos((prev) => [...prev, newTodo]);//기존 todo값에 접근해 뒤에 새로운 todo생성.
setText("");
};
//Delete Todo : 삭제 이모티콘 터치 시 해당 todo 삭제!!alert쓴다.
const deleteTodo = (id) => {
//alert.alert(제목,내용,[{취소시 행동},{삭제시 행동}])
Alert.alert("Todo삭제", "삭제하시겠습니까", [
{
text: "취소",
style: "cancel",
onPress: () => console.log("취소됨"),
},
{
text: "삭제",
style: "destreutive",
onPress: () => {
//삭제를 눌렀을 때 나오는 행동.
//1. id값을 받아서 해당 배열 요소를 제외한 나머지르 새로운 배열로 받는다.
//2. setTodos
//얕은 복사대신 왜 직접 todo를 지정하는가.
//filter는 immutable메소드라서 todos에 영향을 미치지 못한다..
const newTodos = todos.filter((todo) => todo.id !== id);
setTodos(newTodos);
},
},
]);
};
//edit : 수정을 누르면 input창이 뜸.
const isEdit = (id) => {
const newTodos = [...todos];
const idx = newTodos.findIndex((todo) => todo.id === id);
newTodos[idx].isDone = !newTodos[idx].isDone;
setTodos(newTodos);
};
const editTodo = (id) => {
//1.id값을 받아서 해당 배열의 요소[idx]를 찾음.
//2. todos[idx].text = editText; (얕은복사)
const newTodos = [...todos];
const idx = newTodos.findIndex((todo) => todo.id === id);
newTodos[idx].text = editText;
//수정을 마친다음 isEdit창을 닫아줘야 한다.
newTodos[idx].isEdit = false;
setTodos(newTodos);
};
//컴포넌트가 마운트 됐을 때 로컬 스트리지 대신 에이씽크 스토리지를 사용하여 데이터 유지 async 임포트 해야함.
//대신 비동기로 사용함.(함수안에서만 쓸 수 있는 제약조건이 있다..)
useEffect(()=> {
const saveTodo = async() => {
//todos가 변할때 마다 현재 상태를 저장.
await AsyncStorage.setItem("todos",JSON.stringify(todos))
//getData를 하지않아도 얘는 자동으로 읽어준다.todos가 원래는 빈배열이니까..뭘..생성하면...그떄부터 렌더링되게..
if (todos.length >0) saveTodo();
}},[todos])
useEffect(() => {
const getData = async () => {
const res = await AsyncStorage.getItem("todos");
const resCate = await AsyncStorage.getItem("category");
//파싱한 값을 가지고 setTodos를 한다.최초 렌더링 되자마자 기억한 값을 보여준다.
setTodos(JSON.parse(res));
}
getData();
},[])
const setCate = async (cat) => {
setCategory(cat);
//얘는 걍 문자열이라 JSON.stringify생략해도 상관없다.
await AsyncStorage.setItem("category",(cat))
}
return (
<View style={styles.container}>
<StatusBar style="auto" />
<SafeAreaView style={styles.headerText}>
<TouchableOpacity
style={{
...styles.HeaderButton,
//스타일의 조건문.
backgroundColor: setCate === "js" ? "#ffff00" : "#ffaa00",
}}
onPress={() => "js"}
>
<Text>Javascript</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
...styles.HeaderButton,
backgroundColor: setCate === "react" ? "#ffff00" : "#ffaa00",
}}
onPress={() => "react"}
>
<Text>react</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
...styles.HeaderButton,
backgroundColor: setCate === "ch" ? "#ffff00" : "#ffaa00",
}}
onPress={() => "ch"}
>
<Text>ch</Text>
</TouchableOpacity>
</SafeAreaView>
<TextInput
style={styles.TextInput}
placeholder="아무거나 입력해주세요."
onSubmitEditing={addTodo}
onChangeText={setText} //함수가 들어가면 되는데 setText가 함수라 그냥 넣어도 상관X.공식홈페이지에 Textinput페이지에 대놓고 나온다.참고...
value={text}
/>
{todos.map((todo) => {
//이중포문을 쓴것이다.조건문을 주기위해 {}로 감싸기.
if (category === todo.category) {//카테고리가 todo의 카테고리와 같으면 리턴하기
return (
<View key={todo.id} style={styles.bodyContainer}>
{todo.isEdit ? (
<TextInput
style={styles.TextInput}
placeholder="아무거나 입력해주세요."
onSubmitEditing={() => editTodo(todo.id)}
onChangeText={setEditText} //함수가 들어가면 되는데 setText가 함수라 그냥 넣어도 상관X.공식홈페이지에 Textinput페이지에 대놓고 나온다.참고...
value={edittext}
/>
) : (
<Text
style={{
...styles.Todo,
textDecorationColor: todo.isDone ? "line-threough" : "none",
}}
>
{todo.text}
</Text>
)}
<Text
style={{
...styles.Todo,
textDecorationLine: todo.isDone ? "line-threough" : "none",
}}
>
{todo.text}
</Text>
<TouchableOpacity>
<AntDesign
name="edit"
size={24}
color="black"
onPress={() => setDone(todo.id)}
/>
</TouchableOpacity>
<TouchableOpacity onPress={() => setEdit(todo.id)}>
<AntDesign name="checkcircleo" size={24} color="black" />
</TouchableOpacity>
<TouchableOpacity>
<AntDesign
name="delete"
size={24}
color="black"
onPress={() => deleteTodo(todo.id)}
/>
</TouchableOpacity>
</View>
);
}
})}
</View>
);
}
#과제
에이씽크 스토리지 다 빼고
몽고db면 firestore 로그인 안해도 등록이 가능하다고 함...json서버 사용해도 무관함.
프로젝트 만들고 ios랑 and말고 web으로 무조건 선택하기!!!
파이어베이스 스니펫 그대로 써도디는데 cdn이 아니라 npm firebase다운받기 때문에 프로젝트 셋업때 프로젝트 설정 ->npm install firebase옮겨서 사요ㅕㅇ한다.
'[내일배움캠프] > TIL' 카테고리의 다른 글
23.01.03) React native 심화(navigate)를 배운 47일차 (0) | 2023.01.03 |
---|---|
23.01.02) React native 복습 및 배운 46일차 (0) | 2023.01.02 |
22.12.29) expo설치,React native(ui)를 배운 44일차 (0) | 2022.12.29 |
22.12.28) React팀프로젝트를 마무리한 43일차 (0) | 2022.12.29 |
22.12.27) React팀프로젝트와 메인을 작업한 42일차 (0) | 2022.12.27 |