css, routing, form

2024. 3. 24. 16:42Daily 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