관리 메뉴

java,javascript,android,php,sql,공부용,메모용

React 프론트 영역 / 생활코딩 본문

javascript, jQuery & Node.js/React

React 프론트 영역 / 생활코딩

yy_dd2 2022. 8. 8. 18:24
반응형

React에 대해서 조금이라도 알고 넘어거야 할 거 같아서 화면구성을 어떻게 하고

html으로 표현했던 화면들이 어떤 코딩으로 구성되는지 생활코딩을 통해서 알아봤다

 

생활코딩에서는 CRUD 화면구성 화면 전환에 대해서 알려줬는데

한번 쭉 듣고 해본 내용으로는 페이지를 계속 만드는 것이 아닌 새로 리로드를 하지 않고 화면을 불러와서 뿌려주는 것으로 화면을 전환한다

한페이지에 많은 내용을 작성해야 하는 불편함이 있는거 같은데 이후에 데이터까지 연결하고 백엔드까지하면 어떤 관리가 이루어져야 하는지 세세한 내용이 궁금해졌다

 


* 맨처음 아무것도 없을때 새폴더 터미널 작성 "."은 현재폴더 -> npx create-react-app .   

* 이후 새 프로젝트를 생성하기 위해 새 폴더를 만들어서 할때 

터미널 -> npm init react-app .

npm init react-app react-app-todolist

* react 터미널 실행 명령어

 npm start
   개발 서버를 시작합니다.


  npm run build
    프로덕션을 위해 앱을 정적 파일로 묶습니다.
배포판을 만드는 것 
-> 빌드라는 폴더가 생기고 index.html….파일이 있는데 공백을 제거한 파일이 생성된다
-> npx server -s build   라고 실행하면 빌드된 폴더의 index.html 파일을 실행해줌


  npm test
    테스트 러너를 시작합니다.


  npm run eject
    이 도구를 제거하고 빌드 종속성, 구성 파일을 복사합니다.
     스크립트를 앱 디렉토리에 넣습니다. 이렇게 하면 되돌릴 수 없다!

 

 

* render

랜더는 src index.js을보면 id가 root인 것으로 랜더 한다는 것이 보이는데[

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(

  <React.StrictMode>

    <App />

  </React.StrictMode>

);

public 폴더의 index.html 안에 body 안에 id=root 로 감싸진 것 

 

 

 

* 컴포넌트 :  사용자 정의 태그 ->함수를 만들면 된다

react에서 함수를 만들때 첫글자는 반드시 대문자

 

* 리액트는 속성을 props (프롭스) 이라고 한다

 

* state (스테이트)

컴포넌트는 입력과 출력이 있다 [입력 prop] [출력 return]

state : prop과 같이 컴포넌트 함수를 다시 실행해서 새로운 리턴값을 만들어주는 것

prop과 state의 차이는

prop은 외부 사용자를 위한 데이터

state는 내부자를 위한 데이터

 

 

reactDOM 이랑 react-router-dom 은 다른 새페이지를 추가하는 것을 따로 연습해본것 

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
  
);

app.js

import logo from './logo.svg';
import './App.css';
import {useState} from 'react';
import { BrowserRouter, Route } from "react-router-dom";
//import Home from './pages/home.js';
//import Test from './pages/test.js';
import { Home, Test } from "./pages";


function Article(props) {
  return <article>
    <h2>Welcome -&gt; {props.title}</h2>
    Hello, WEB -&gt; {props.body}
  </article>
}

function Header(props) {
  //console.log("props",props)
  return <header>
    {/* <h1><a href='/' onClick={function(evnet){ */}
    <h1><a href='/' onClick={(evnet)=>{
      evnet.preventDefault(); //페이지 리로드 방지 이벤트를 제어하는 파라미터로 (event) 값을 주고 이벤트 제어 preventDefault 를 사용한다.
      props.onChangeMode();
    }}>React -&gt; {props.title}</a></h1>
  </header>
}
function Nav(props) {
  const lis = [
    // <li><a href='/read/1'>html</a></li>,
    // <li><a href='/read/2'>css</a></li>,
    // <li><a href='/read/3'>js</a></li>
  ]
  for(let i = 0; i<props.topics.length; i++){
    let t = props.topics[i];
    lis.push(<li key={t.id}>
      <a id={t.id} href={'/read/'+t.id} onClick={event=>{
        event.preventDefault();
        //props.onChangeMode(t.id);
        props.onChangeMode(Number(event.target.id));  //.target : 이벤트를 유발시킨 태그를 가리킨다 a태그  (a태그의 id값 가져옴)
      }} >{t.title}</a>
      </li>)
    // 추적의 근거로 작동하게 key 를 준다
  }
  return <nav>
    <ol>
      {lis}
    </ol>
  </nav>
}
function Create(props) {  
  return <article>
    <h2>Create</h2>
    <form onSubmit={event=>{
      event.preventDefault();
      const title = event.target.title.value;
      const body = event.target.body.value;
      // 가져온걸 전달
      props.onCreate(title, body);
    }}>
      <p><input type="text" name="title" placeholder="title" /></p>
      <p><textarea name="body" placeholder='body'></textarea></p>
      <p><input type="submit" value='Create'></input></p>
    </form>
  </article>
}

function Update(props) {
  const [title, setTitle] = useState(props.title);
  const [body, setBody] = useState(props.body)
    return <article>
    <h2>Update</h2>
    <form onSubmit={event=>{
      event.preventDefault();
      const title = event.target.title.value;
      const body = event.target.body.value;
      // 가져온걸 전달
      props.onUpdate(title, body);
    }}>
      <p><input type="text" name="title" placeholder="title" value={title} onChange={evnet=>{
        setTitle(evnet.target.value);
      }} /></p>
      <p><textarea name="body" placeholder='body' value={body} onChange={event=>{
        setBody(event.target.value);
      }}></textarea></p>
      <p><input type="submit" value='Update'></input></p>
    </form>
  </article>
}

function App() {
  // useState 0번째는 상태의 값을 읽을때 1번째 상태의 값을 변경할때 사용하는 함수
  // const _mode = useState('WELCOME');  //초기값
  // const mode = mode[0];       // 읽는 값
  // const setMode = _mode[1];   // 바뀌는 값
  const [mode, setMode] = useState('WELCOME');// mode의 이름은 원하는대로
  const [id, setId] = useState(null);
  const [nextId, setNextId] = useState(4);    // 4부터 시작
  //const topics = useState [          
  const [topics, setTopics] = useState ([  // Create 추가된 코드
    {id:1, title:'html', body:'html is ...'},
    {id:2, title:'css', body:'css is ...'},
    {id:3, title:'javascript', body:'javascript is ...'}
  ])
  let content = null;
  let contextControl = null; 
  if(mode === 'WELCOME'){
    content = <Article title="Welcome" body="Hello, WEB"></Article>
  } else if (mode === 'READ'){
    let title, body = null;
    for(let i=0; i<topics.length; i++){
      console.log(topics[i].id, id);
      if(topics[i].id === id){
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body}></Article>
    contextControl = <><li><a href={'/update/'+id} onClick={evnet=>{
      evnet.preventDefault();
      setMode('UPDATE');
    }}>Update</a></li>
    <li>
      <input type='button' value="Delet" onClick={()=>{
        const newTopics = []
        for(let i=0; i<topics.length; i++){
          if(topics[i].id !== id){      // 현재 선택한 id와 토픽스의 아이디가 다를 때
            newTopics.push(topics[i]);  // 아이디가 일치하지 않는 토픽만 준다
          }
        }
        setTopics(newTopics);
        // 홈으로 이동
        setMode('WEWELCOME');
      }} />
    </li>
    </>
  } else if (mode === 'CREATE') {
    content = <Create onCreate={(_title, _body)=>{
      // topics 에 추가하기 위해서 useState 상태로 올려준다
      const newTopic = { id: nextId, title : _title, body : _body};
      // id값 별도 관리 새 id값 변수로 만들어줌
      // 토픽스에 newToipic를 추가하기
      const newTopics = [...topics]
      newTopics.push(newTopic);
      setTopics(newTopics);
      setMode("READ");
      setId(nextId);
      setNextId(nextId+1);
    }}></Create>
  } else if (mode === 'UPDATE') {
    let title, body = null;
    for(let i=0; i<topics.length; i++){
      console.log(topics[i].id, id);
      if(topics[i].id === id){
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Update title={title} body={body} onUpdate={(_title, _body)=>{
      const newTopics = [...topics];
      const updateTopic = {id:id, title: _title, body:_body}  // READ를 한 상태로만 불러오기 때문에 id가 있다
      for(let i=0; i<newTopics.length; i++){
        if(newTopics[i].id === id){
          newTopics[i] = updateTopic;
          break
;        }
      }
      setTopics(newTopics);
      setMode('READ');  // 상세보기로 이동
    }}></Update>
  }
  return (
    <div>
      {/* <Header title="WEB" onChangeMode={function(){ */}
      <Header title="WEB" onChangeMode={()=>{
        //alert('Header onChangeMode');
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id)=>{
        //alert(id);
        setMode('READ');
        setId(_id);
      }}></Nav>
      {/* <Article title="Welcome" body="Hello, WEB"></Article> */}
      {content}
      <ul>
        <li><a href='/create' onClick={event=>{
          event.preventDefault();
          setMode('CREATE');
        }}>Create</a></li>
        {contextControl}
        {/* 사용자가 제목을 눌러 내용을 볼 때 나타나도록 지역변수를주고 mode가 READ 일 때 나타나도록 했다 */}
        
      </ul>

        {/* <BrowserRouter>
            <Route path="/" component={Home} exact />
            <Route path="/test" component={Test} />
        </BrowserRouter> */}
 
    </div>
  );
}

export default App;

코드 옮겨놓구 보니까 더럽게 주석을 걸었는데

그리고 티스토리에서 리액트는 잘 안봐주나보다 색이 다 검정색이된다.... 메모용이니 넘어간다 

반응형
Comments