css, routing, form
2024. 3. 24. 16:42ㆍDaily Codig Reminder
Routing10_action함수1_Form태그서버전송2_예외처리_useActionData이용
import React from 'react';
import Home from './pages/Home'
import Products from './pages/Products'
import Root from './pages/Root';
import UsersRoot from './pages/UsersRoot';
import NewUser from './pages/NewUser';
import Error from './pages/Error';
import ProductDetails from './pages/ProductDetails';
import ProductDetails2 from './pages/ProductDetails2';
import UsersPage from './pages/User';
import { action as newUserAction } from './pages/NewUser';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import { loader as usersLoader } from './pages/User';
const router = createBrowserRouter([
{
path: "/",
element: <Root/>,
errorElement: <Error/>, ///////////////// 추가
////////////////////////////////////////
id:"root",/////////////////////////
loader: async function () {
console.log("loader root >>>>>");
const response =await fetch("https://reqres.in/api/users?page=1");
const resData = await response.json();
return resData.data;
},
children: [
{ path: "/", element: <Home/> },
{ path: "/products", element: <Products/> },
{
path: "/users/",
element : <UsersRoot/>,
//index:true 부모와 동일한 주소 사용
children: [
{index : true, element: <UsersPage/>, loader: usersLoader},
{path: "new" , element: <NewUser/>, action: newUserAction}
],
// element: <UsersPage/>,
// loader: usersLoader, //error occur
// loader: async function () {
// console.log("loader>>>>>");
// try {
// const response = await axios.get("https://reqres.in/api/users?page=2");
// return response.data.data;
// } catch (error) {
// console.error("Error loading users:", error);
// return [];
// }
// }
}, ////////////////추가
{ path: '/products/:productId', element: <ProductDetails/> }, ///////추가
{ path: '/products2', element: <ProductDetails2/> },
]
},
]);
function App(props) {
return (
<>
<RouterProvider router={router}/>
</>
);
}
export default App;
import React from 'react';
import UserList from '../components/UserList';
import { useLoaderData } from 'react-router-dom';
import { json } from 'react-router-dom'; ///////////////////////
function UsersPage(props) {
// const events = useLoaderData(); //App.js 의 데이터를 로드
return (
<div>
<h1>The Users Page</h1>
<UserList />
</div>
);
}
//app.js 에서 등록 사용
export async function loader(){
try{
console.log("Users.lader 실행>>>>>");
const response = await fetch("https://reqres.in/api/users?page=2")
const resData = await response.json();
console.log(resData);
return resData.data;
}catch(error){
console.log("catch error", error);
////////////////////////////// 추가
throw json({message: "could not fetch users" , status: 500})// import
//error.js 수정 useRouter() 로 사용중
}
}
export default UsersPage;
import React from 'react';
import { redirect,Form, useNavigate, json } from 'react-router-dom';
function NewUser(props) {
const navigate = useNavigate();
const cancelHandler=()=>{
navigate ("..");
};
return (
<div>
<h1>The New UsersPage Page</h1>
{/*폼 데이터는 action({request}) 의 requset.forData() 폼 데이터는
action({requset}) 의 request.forData() 로 추출 사용,
app.js 에서 어느 컴포넌트가 처리할 지 등록 필요
리액트에서 제공하는 Form 사용*/}
<Form method='post'>
id: <input type='text' name='id'/><br/>
email : <input type='text' name='email'/><br/>
first_name: <input type='text' name='first_name'/><br/>
last_name: <input type='text' name='last_name'/><br/>
<button onClick={cancelHandler} >cancle</button><br/>
<button>save</button>
</Form>
</div>
);
}
// app.js 에서 등록이 필요
export async function action({request, params}){
const data= await request.formData();
const eventData = {
id: data.get("id"),
email: data.get("email"),
first_name: data.get("first_name"),
last_name: data.get("last_name")
};
console.log("NewUsers.action ======" , eventData);
const response = await fetch("https://reqres.in/api/users", {
method: "POST",
body: JSON.stringify(eventData),
headers: {
"Content-Type": "application/json",
}
});
if (!response.ok){
throw json({message : "Could not save user."}, {status : 500});
}
//실습서비인 reqres.in 에 잘 전송되었는지 확인용
const resData = await response.json();
console.log("resData : ", resData);
return redirect ("/users") //실제 서버에 추가되지는 않음
}
export default NewUser;
import React from 'react';
import { NavLink } from 'react-router-dom';
import classes from './MainNavigation.module.css'
function UsersNavigation(props) {
return (
<>
<NavLink
to="/users"
className={({isActive}) => {
return isActive ? classes.menu : undefined;
}}>
All users
</NavLink><br/>
<NavLink
to="/users/new"
className={({isActive}) => {
return isActive ? classes.menu : undefined;
}}>
New users
</NavLink><br/>
</>
);
}
export default UsersNavigation;
import React from 'react';
import { Outlet, useNavigation } from 'react-router-dom';
import UsersNavigation from '../components/UsersNavigation';
function UsersRoot(props) {
const navigation = useNavigation(); ///////////
return (
<div>
<UsersNavigation/>
<hr/>
{navigation.state === "loading" && <p>Loading...</p>}
{/* {navigation.state === "loading" && alert("Loading...")} */}
{/*추가부분*/}
<Outlet/>
</div>
);
}
export default UsersRoot;
import axios from "axios";
export async function fetchUserList(){
let resData;
// try{
// //데이터 요청 응답 수신
// const response = await axios({
// url: "https://reqres.in/api/users?page=2",
// //method:"GET" //정상요청
// method:"GET" //정상요청
// //에러 실습은 PUT 으로 변경해서 테스트 할것
// });
// resData = await response.data.data;
// }catch(error){
// console.log(error);
// throw new Error(" 목록 로딩시 발생");
// }
//1.
// await axios({
// method: "get",
// url: "https://reqres.in/api/users?page=2",
// }).then(
// (res) => {
// console.log(">>>>>>",res);
// resData= res.data.data;
// }
// ).catch(
// (error) => {
// console.log(error);
// throw new Error("목록 로딩시 발생")
// }
// )
//2.
await axios.get(
"https://reqres.in/api/users?page=2"
).then(
(res) => {
console.log(">>>>>>",res);
resData= res.data.data;
}
).catch(
(error) => {
console.log(error);
throw new Error("목록 로딩시 발생")
}
)
return resData;
}
export async function insertUser(user){
let resData;
try{
const response = await axios({
method: "POST",
body: JSON.stringify(user),
headers: {
"Content-type" : "application/json",
},
url:"https://reqres.in/api/users"
})
resData = response.data.data;
}catch(error){
console.log(error);
throw new Error ("회원 추가시 에러 발생");
}
return resData;
}


form01_state / ref/ formData이용 /blur
form01_state이용
import React, { useState } from 'react';
function Login(props) {
const [inputs, setInputs] = useState({
email: "",
password: "",
});
function handleSubmit(event) {
event.preventDefault();
console.log(inputs);
}
function handleInputChange(name, value) {
setInputs({
...inputs,
[name]: value
});
}
return (
<div>
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div>
<div>
<label htmlFor='email'>Email</label>
<input
type='email'
id='email'
name='email'
onChange={(event) =>
handleInputChange('email', event.target.value)
}
value={inputs.email}
/>
</div>
<div>
<label htmlFor='password'>Password</label>
<input
type='password'
id='password'
name='password'
onChange={(event) =>
handleInputChange('password', event.target.value)
}
value={inputs.password}
/>
</div>
</div>
<button type='submit'>Login</button>
</form>
</div>
);
}
export default Login;

ref이용
import React, { useState, useRef } from 'react';
function Login(props) {
const [inputs, setInputs] = useState({
email: "",
password: "",
});
const emailInputRef = useRef(null);
const passwordInputRef = useRef(null);
function handleSubmit(event) {
event.preventDefault();
console.log(inputs);
// 여기에서 로그인 로직을 추가할 수 있습니다.
const enteredEmail = emailInputRef.current.value;
const enteredPassword = passwordInputRef.current.value;
console.log(enteredEmail,'\t', enteredPassword);
}
function handleInputChange() {
setInputs({
email: emailInputRef.current.value,
password: passwordInputRef.current.value
});
}
return (
<div>
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div>
<div>
<label htmlFor='email'>Email</label>
<input
type='email'
id='email'
ref={emailInputRef}
onChange={handleInputChange}
value={inputs.email}
/>
</div>
<div>
<label htmlFor='password'>Password</label>
<input
type='password'
id='password'
ref={passwordInputRef}
onChange={handleInputChange}
value={inputs.password}
/>
</div>
</div>
<button type='submit'>Login</button>
</form>
</div>
);
}
export default Login;

FormData객체이용
import React from 'react';
function Signup(props) {
function handleSubmit(event){
event.preventDefault();
const fd = new FormData(event.target);
const email = fd.get("email");
const password = fd.get("password");
const address = fd.get("address");
console.log(email, password, address);
}
return (
<div>
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div>
<div>
<label htmlFor="email">Email</label>
<input id="email" name="email" type="email"></input>
</div>
<div>
<label htmlFor="password">password</label>
<input id="password" name="password" type="password"></input>
</div>
<div>
<label htmlFor="address">address</label>
<input id="address" name="address" type="text"></input>
</div>
<div>
<label htmlFor="address2">address2</label>
<input id="address2" name="address2" type="text"></input>
</div>
</div>
<button>Login</button>
</form>
</div>
);
}
export default Signup;

유효성검사_blur시점에
import React, { useState } from 'react';
function Login() {
const [inputs, setInputs] = useState({
email: "",
password: "",
});
const [didEdit, setDidEdit] = useState({
email: false,
password: false
});
const emailIsInvalid = didEdit.email && !inputs.email.includes("@");
const passwordIsInvalid = didEdit.password && !(inputs.password.length > 6);
function handleSubmit(event) {
event.preventDefault();
console.log(inputs);
}
function handleInputChange(name, value) {
setInputs({
...inputs,
[name]: value
});
}
function handleInputBlur(name) {
setDidEdit({
...didEdit,
[name]: true
});
}
return (
<div>
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div>
<div>
<label htmlFor='email'>Email</label>
<input
type='email'
id='email'
name='email'
onBlur={() => handleInputBlur("email")}
onChange={(event) =>
handleInputChange('email', event.target.value)
}
value={inputs.email}
/>
{emailIsInvalid && <p>Email is invalid</p>}
emailIsInvalid###{emailIsInvalid ? "true" : "false"}
</div>
<div>
<label htmlFor='password'>Password</label>
<input
type='password'
id='password'
name='password'
onBlur={() => handleInputBlur("password")}
onChange={(event) =>
handleInputChange('password', event.target.value)
}
value={inputs.password}
/>
{passwordIsInvalid && <p>Password is invalid</p>}
passwordIsInvalid###{passwordIsInvalid ? "true" : "false"}
</div>
</div>
<button type='submit'>Login</button>
</form>
</div>
);
}
export default Login;

css
inline방식
import React from 'react';
function App(props) {
//css 설정, json, camel 표기법
const btnStyle={
color:"white",
backgorundColor: "teal",
border: "1px sild teal",
fontSize: "16px"
};
return (
<>
<button style={btnStyle}>Inline</button>
</>
);
}
export default App;

external방식
import React from 'react';
import "./Button.css"
function App(props) {
//css 설정, json, camel 표기법
const btnStyle={
color:"white",
backgorundColor: "teal",
border: "1px sild teal",
fontSize: "16px"
};
return (
<>
<button className='btn'>Inline</button>
</>
);
}
export default App;
.btn{
color: red;
background-color: teal;
font-size: 16px;
}

npm install styled-components
styled_component01기본
import React from 'react';
//npm install styled-components
import styled from 'styled-components';
function App(props) {
//css 설정, json, camel 표기법
const StyledButton = styled.button`
color: blue;
background-color: yellow;
font-size: 16px;
`;
return (
<>
<StyledButton>styled components</StyledButton>
</>
);
}
export default App;

styled_component01기본2_외부파일2_children전달
import React from 'react';
//npm install styled-components
import styled from 'styled-components';
import Button from './Button';
function App(props) {
//css 설정, json, camel 표기법
const StyledH1 = styled.h1`
color: red;
`;
return (
<>
<StyledH1>Hello</StyledH1>
<Button>
<ul>
<li>A</li>
<li>B</li>
</ul>
</Button>
</>
);
}
export default App;
import React from 'react';
import styled from 'styled-components';
const StyledButton = styled.button`
color: blue;
background-color: yellow;
font-size: 16px;
`;
function Button({ children }) {
return (
<StyledButton>
{children}
</StyledButton>
);
}
export default Button;

import React from 'react';
//npm install styled-components
import styled from 'styled-components';
import Button from './Button';
function App(props) {
//css 설정, json, camel 표기법
const StyledH1 = styled.h1`
color: red;
`;
const text_color = "pink"
return (
<>
<StyledH1>Hello</StyledH1>
<Button text_color={text_color}>
<ul>
<li>A</li>
<li>B</li>
</ul>
</Button>
</>
);
}
export default App;
import React from 'react';
import styled from 'styled-components';
const StyledButton = styled.button`
color: ${(props) => props.button_color || "blue"};
background-color: yellow;
font-size: 16px;
`;
function Button({ children , text_color}) {
return (
<StyledButton button_color ={text_color}>
{children}
</StyledButton>
);
}
export default Button;

css2
styled_component01기본2외부파일3동적처리props2멀티속성
import React from 'react';
//npm install styled-components
import styled from 'styled-components';
import Button from './Button';
function App(props) {
//css 설정, json, camel 표기법
const StyledH1 = styled.h1`
color: red;
`;
const text_color = "pink"
const text_font_size ="16px";
return (
<>
<StyledH1>Hello</StyledH1>
<Button text_color={text_color}
text_font_size={text_font_size}>
<ul>
<li>A</li>
<li>B</li>
</ul>
</Button>
</>
);
}
export default App;
import React from 'react';
import styled from 'styled-components';
const StyledButton = styled.button`
color: ${(props) => props.text_color || "blue"};
background-color: yellow;
font-size: ${(props) => props.text_font_size|| "64px"}
`;
function Button({ children , ...props}) {
return (
<StyledButton {...props}
>
{children}
</StyledButton>
);
}
export default Button;

import React from 'react';
//npm install styled-components
import styled from 'styled-components';
//1. 태그의 스타일 적용 : styled 태그명 `` 형식
const Box = styled.div `
width: 100px;
height: 100px;
background-color: ${(props) => props.bgColor};
`;
//2. style 상속하기 (확장)
const Circle = styled(Box)`
border-radius: 50%;
`;
function App(props) {
return (
<div>
<Box bgColor={"red"} >Box1</Box>
<Circle bgColor={"yellow"}>Box2</Circle>
</div>
);
}
export default App;

import React from 'react';
//npm install styled-components
import styled from 'styled-components';
import classes from './App.css'; //일반 css 는 "" 이용 사용
import classes2 from './test.module.css';
function App(props) {
return (
<div>
<h1 className='test'>test1</h1>
<h1 className={classes.test}>test2</h1>
<h1 className={classes2.test2}>test3</h1>
<h1 className='test2'>test4</h1>
</div>
);
}
export default App;

'Daily Codig Reminder' 카테고리의 다른 글
selectOne/delete/template (0) | 2024.03.28 |
---|---|
Node.js (0) | 2024.03.28 |
Routing_loader (0) | 2024.03.24 |
axios, router (0) | 2024.03.24 |
useEffect , memo (0) | 2024.03.19 |