6-8 React에서 API호출 

JSONplaceholder 서비스 이용 

Resources 에 가서 comment를 사용할 것임.

const initData = res.slice(0, 20).map((it) => {
      return {
        author: it.email,
        content: it.body,
        emotion: Math.floor(Math.random() * 5) + 1,
        created_date: new Date().getTime() + 1,
        id: dataId.current++
      };
    });

    setData(initData);
  };

Math.random은 정수가 반환되지 않음 그러므로  정수로 바꿔주는 math.floor 를 사용해줌 

created_date는 현재시간으로 생성

...

 

완성된 init데이터를 셋데이터에 넣어줌 ! 

 

6-9 react developer tools

크롬의 확장 도구 

 

6-10 최적화1 use demo

리액트에서 메모이제이션

const getDiaryAnalysis = useMemo(() => {
    if (data.length === 0) {
      return { goodcount: 0, badCount: 0, goodRatio: 0 };
    }
    console.log("일기 분석 시작");

    const goodCount = data.filter((it) => it.emotion >= 3).length;
    const badCount = data.length - goodCount;
    const goodRatio = (goodCount / data.length) * 100.0;
    return { goodCount, badCount, goodRatio };
  }, [data.length]);

  const { goodCount, badCount, goodRatio } = getDiaryAnalysis;
  
  return (
    <div className="App">
      <DiaryEditor onCreate={onCreate} />
      <div>전체 일기 : {data.length}</div>
      <div>기분 좋은 일기 개수 : {goodCount}</div>
      <div>기분 나쁜 일기 개수 : {badCount}</div>
      <div>기분 좋은 일기 비율 : {goodRatio}</div>
      <DiaryList onEdit={onEdit} onRemove={onRemove} diaryList={data} />
    </div>
  );

usememo를 사용하기 위해서는 memoization하고 싶은 함수를 감싸주면 됨 . 

callback 함수가 리턴하는 것을 도와줌 

 

usememo로 감싸고 최적화를 하면 더이상 함수가 아니게 됨. 

그러므로 값으로 사용해야함 (안그러면 에러남) 

 

6-11 최적화2- 컴포넌트 재사용 

optimizetext.js

import React, { useEffect, useState } from "react";

const CounterA = React.memo(({ count }) => {
  useEffect(() => {
    console.log(`CountA Update - count : ${count}`);
  });
  return <div>{count}</div>;
});

const CounterB = ({ obj }) => {
  useEffect(() => {
    console.log(`CountB Update - count : ${obj.count}`);
  });
  return <div>{obj.count}</div>;
};

const areEqual = (prevProps, nextProps) => {
  if (prevProps.obj.count === nextProps.obj.count) {
    return true;
  }
  return false;
};

const MemoizedCounterB = React.memo(CounterB, areEqual);

const OptimizeTest = () => {
  const [count, setCount] = useState(1);
  const [obj, setObj] = useState({
    count: 1
  });

  return (
    <div style={{ padding: 50 }}>
      <div>
        <h2>Counter A</h2>
        <CounterA count={count} />
        <button onClick={() => setCount(count)}>A Button</button>
      </div>
      <div>
        <h2>Counter B</h2>
        <MemoizedCounterB obj={obj} />
        <button onClick={() => setObj({ count: 1 })}>B Button</button>
      </div>
    </div>
  );
};

export default OptimizeTest;

6-12 최적화3 

  useEffect(() => {
    setTimeout(() => {
      getData();
    }, 1500);
  }, []);

  const onCreate = useCallback((author, content, emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author,
      content,
      emotion,
      created_date,
      id: dataId.current
    };

    dataId.current += 1;
    setData((data) => [newItem, ...data]);
  }, []);

  const onRemove = (targetId) => {
    const newDiaryList = data.filter((it) => it.id !== targetId);
    setData(newDiaryList);
  };

  const onEdit = (targetId, newContent) => {
    setData(
      data.map((it) =>
        it.id === targetId ? { ...it, content: newContent } : it
      )
    );
  };

함수형 업데이트 

 

6-14 최적화4

  const onCreate = useCallback((author, content, emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author,
      content,
      emotion,
      created_date,
      id: dataId.current
    };

    dataId.current += 1;
    setData((data) => [newItem, ...data]);
  }, []);

  const onRemove = useCallback((targetId) => {
    setData((data) => data.filter((it) => it.id !== targetId));
  }, []);

  const onEdit = useCallback((targetId, newContent) => {
    setData((data) =>
      data.map((it) =>
        it.id === targetId ? { ...it, content: newContent } : it
      )
    );
  }, []);

'개발 > React 스터디' 카테고리의 다른 글

리액트 5주차  (0) 2023.05.21
리액트 3주차  (0) 2023.04.30
리액트 2주차  (0) 2023.04.08
리액트 1주차  (0) 2023.04.02

6-2 React에서 DOM조작하기 

handle submit 기능을 수정 

 

console.log(state) ---> 

if(state.author.length<1){
	alert ("작성자는 최소 1글자 이상 입력해 주세요");
return;
}
if(state.author.length<5){
	alert ("일기 본문은 최소 5글자 이상 입력해주세요");
return;
}

저장하기 버튼을 클릭했을 때 조건에 맞지 않으면 alert가 나오게 되는 것을 확인 할 수 있다.

 

하지만 트렌디한 웹사이트에서는 이러한 alert를 잘 사용하지 않는다. 

그래서  우리는 alert대신 focus를 주는 방법을 적용해 볼 것이다. 

 

 

use Ref를 사용

const authorInput =useRef();를 사용해서user input에 user Ref를 적용시킴

그러면 authorinput에는 React.MutableRefObject가 적용됨 

<input 
ref=(authorInput)
	name='author'
    type='text'
    value={state.author}
    onChange={handleChangeDiary}
/>

author input이라는 객체를 통해서 인풋에 접근할 수 있게 됨 

 

이제 아까 작성한 alert를 없애고  authorInput.current.focus();를 입력해주면된다. 

 

textarea도 이런식으로 적용해주면 된다. 

 

6-3 react에서 리스트 사용하기 

작성된 일기들은 array에 저장되고 list 형태로 렌더링 됨 

 

diaryList.js 생성

const DiaryList=()=>{
	return<div className='DiaryLsit">
    	<h2>일기 리스트</h2>
    </div>
}

export default DiaryList;

 

app.js 수정 

import ...

const dummyList=[
	id:
    author:
    content:
    emotion:
    create_date:
],

const App=()=>{
	return (
    	<div className='App'>
        	<diaryEditor/>
            <diaryList/>
        </div>
    );
};
export default App;

 

일기 데이터 사용하는 방법 

작성사 사용 

<div>작성자: {it.author}</div>를 추가해주면 됨 

일기는 

<div>일기:{it.content}</div>

이런식으로 배열의 요소를 리스트 형태로 나타나느 것을 확인 할 수 있음 

 

undefined으로 설정된 값을 디폴드 값으로 전달해 주는 방법 

DiaryList.defaultProps={

    diaryList:[ ],

};

 

error가 해결이 됨 

 

 

DiaryItem.js을 별도로  추가

const DiaryItem=()=>{
	return <div className="DiaryItem"></div>;
};

export default DiaryItem;

 

 

 

6-4 리스트 데이터 추가하기

 

컴포넌트&데이터 구조 생각해보기

                <diaryEditor/>

<app/>[

                <diaryList/>

 

리액트에서는 같은 레벨(list와 에디터같은 관계)끼리는 데이터를 주고 받는게 불가능함 

위에서 아래로만 가능함 

<app>--<dummy>--><diarylist>

하지만 다른 방법이 있음.

공통분모인 app이 state를 가지고 있고 list에 data를 주고 editor에 prop으로 상태변환함수인 setdata를 전달해 주면 된다. 

 

이런걸 참고해서 에디터에 추가되면 리스트에 표시되는 것을 확인해 볼 것임 

 

app에 [data,setdata]를 만들어줌 

function App(){
	const [data,setData]=useState([]);
    
    const dateID=useRef(0)
    
    
    const onCreate=(author,content,emotion)=>{
    	const created_date=new Date().getTime();
        const newItem ={
        	author,
            content,
            emotion,
            create_date,
       		id:dataId.current
        };
        dataId.current+=3;
        setDate([...data,newItem]);
    };
return (
	<div className="App">
    ....
    
    .....
const handleSubmit = () => {
        if (state.author.length < 1) {
            authorInput.current.focus();
            return;
        }
        if (state.content.length < 5) {
            contentInput.current.focus();
            return;
        }
        onCreate(state.author, state.content, state.emotion);
        alert("저장 성공");
        setState({
            author: "",
            content: "",
            emotion: 1,
        });
    };

6-5리스트 데이터 삭제하기 

데이터 삭제 함수 ! 

const onDelete(targetId) =>{
        console.log(`${targetId}가 삭제되었습니다`);
        const newDiaryList = data.filter((item) => item.id !== targetId);
        console.log(newDiaryList);
        setData(newDiaryList);
    }
return (
        <div className="App">
            <DiaryEditor onCreate={onCreate}></DiaryEditor>
            <DiaryList onDelete={onDelete} diaryList={data}></DiaryList>
        </div>
    );

6-6 리스트 데이터 수정하기 

const onEdit(targetId, newContent) =>{
        setData(
            data.map((item) =>
                item.id === targetId ? { ...item, content: newContent } : item
            )
        );
    }
    return (
        <div className="App">
            <DiaryEditor onCreate={onCreate}></DiaryEditor>
            <DiaryList
                onDelete={onRemove}
                diaryList={data}
                onEdit={onEdit}
            ></DiaryList>
        </div>
    );
}

'개발 > React 스터디' 카테고리의 다른 글

리액트 5주차  (0) 2023.05.21
리액트 4주차  (0) 2023.05.07
리액트 2주차  (0) 2023.04.08
리액트 1주차  (0) 2023.04.02

5-3  JSX

자바스크립트와 리액트를 혼용해서 사용할 수 있는..!

jsx는 component하는데 필요!

 

 화면에 컴포넌트를 구현하기 위해서는 App이라는 부모페이지에 child 페이지를 포함하고 있어야한다. 

<div className='App'>
	<MyHeader/>
    <header className="App-header">
    	<h2>안녕리액트{name}</h2>
    </header>
</div>

 

 

jsx의 간단한 문법들 

-닫힌규칙

<div>가 있으면 </div>처럼 닫힌 태그가 있어야만 한다

특힌 <image><a><br>처럼 html에서는 닫힌태그를 쓰지 않았던 것들은 주의해야한다

-최상위규칙

다른태그들을 감싸고 있는 가장 바깥쪽 태그가 최상위 태그(부모)이며 이게 없어지면 오류가 발생한다

만약 최상위태그를 사용하고 싶지 않으면 react.fragment를 사용하면 된다. import React from "react"는 필수

-jsx에서는 class 대신 classname

 

 

 

import React from "react";
import "./App.css";

function App() {
  let name = "장도진";

  return (
    <div className='App'>
      <MyHeader />
      <h2>안녕 리액트{name}</h2>
      <b> id='bold_text'> React.js</b>
    </div>
  );
}

export default App;

App.css

.App{
	background-color:black;
}
h2{
	color:red;
}

#bold_text{
	color:green;
}

 

인라인스타일링방식

import React from "react";
//import "./App.css";
import MyHeader from "./MyHeader";

function App() {
  let name = "장도진";

  const style = {
    App: {
      backgroundcolor: "black",
    },
    h2: {
      color: "red",
    },
    bold_text: {
      color: "green",
    },
  };
  return (
    <div style={style.App}>
      <MyHeader />
      <h2 style={style.h2}>안녕 리액트{name}</h2>
      <b style={style.bold_text} id="bold_text">
        React.js
      </b>
    </div>
  );
}

export default App;

5-4STATE

state(상태)란?

계속해서 변화하는 특정 상태, 상태에 따라 각각 다른 동작을 함

ex) 다크모드

App.js

import React from "react";
//import "./App.css";
import MyHeader from "./MyHeader";
import Counter from "./Counter";

function App() {
  const number = 5;

  return (
    <div>
      <MyHeader />
      <Counter/>
    </div>
  );
}

export default App;

Counter.js

import React, { useState } from "react";
const Counter = () => {
  //0에서 출발
  //1씩 증가하고
  //1씩 감소하는
  //count 상태
  const [count, setCount] = useState(0);
  const onIncrease = () => {
    setCount(count + 1);
  };
  const onDecrease = () => {
    setCount(count - 1);
  };
  return (
    <div>
      <h2>{count}</h2>
      <button onClick={onIncrease}>+</button>
      <button onClick={onDecrease}>-</button>
    </div>
  );
};

5-5 props  : 컴포넌트에 데이터를 전달하는 방법

자식컴포넌트에 이름을 붙여서 전달하는 방식  PROPS!!

 

import React, { useState } from "react";
import OddEvenResult from "./OddEvenResult";

const Counter = ({ initialValue }) => {
  const [count, setCount] = useState(initialValue);

  const onIncrease = () => {
    setCount(count + 1);
  };
  const onDecrease = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <h2>{count}</h2>
      <button onClick={onIncrease}>+</button>
      <button onClick={onDecrease}>-</button>
      <OddEvenResult count={count} />
    </div>
  );
};

Counter.defaultProps = {
  initialValue: 0,
};

export default Counter;

의도 치 않게 props가 undefine으로 전달될거 같을 때는

Counter.defaultProps로 initialvalue를 0으로 설정해주면 된다.

const OddEvenResult = ({ count }) => {
  console.log(count);
  return <>{count % 2 === 0 ? "짝수" : "홀수"}</>;
};

export default OddEvenResult;
const Container = ({ children }) => {
  console.log(children);
  return (
    <div style={{ margin: 20, padding: 20, border: "1px solid gray" }}>
      {children}
    </div>
  );
};

export default Container;

 

6-1일기장 만들기 

setAuthor 상태변화 함수

input value=author --> 값을 아무리 입력해도 상태가 변하지 않는다

const [author, setAuthor] = useState("장도진");

 

onChange={(e) => {
console.log(e.target.value);
console.log(e.target.name);
setAuthor(e.target.value);

값이 바뀌었을 때 수행하는 이벤트 

import { useState } from "react";

const DiaryEditor = () => {
  const [state, setState] = useState({
    author: "",
    content: "",
  });

  return (
    <div className="DiaryEditor">
      <h2>오늘의 일기</h2>
      <div>
        <input
          name="author"
          value={state.author}
          onChange={(e) => {
            setAuthor({
              author: e.target.value,
              content: state.content,
            });
          }}
        />
      </div>
      <div>
        <textarea
          value={state.content}
          onChange={(e) => {
            setState({
              content: e.target.value,
              author: state.content,
            });
          }}
        />
      </div>
    </div>
  );
};
export default DiaryEditor;

'개발 > React 스터디' 카테고리의 다른 글

리액트 5주차  (0) 2023.05.21
리액트 4주차  (0) 2023.05.07
리액트 3주차  (0) 2023.04.30
리액트 1주차  (0) 2023.04.02

4-1

자바스크립트 코드는 브라우저 내장 자바스크립트 엔진을 이용하여 실행 

ex) safari, firefox, chrome, edge, opera

 

기존의 자바스크립트는 html기반으로만 동작을 하다보니 웹사이트의 interaction을 수행하는 기능밖에 하지 못했음

but, v8을 브라우저에서 분리하여 자바스크립트를 어디에서든 사용할 수 있게 만들었음 

그것이 바로 node.js 

 

node.js가 생김으로써 javascript로 web server로 개발 가능

 

웹서버란

웹을 반환받으면 웹서버

미디어를 반환받으면 미디어 서버 

채팅을 반화받으면 채팅서버

 

노드와 리액트와의 관계 

리액트는 브라우저에서 동작하는 복잡하고 여러가지 기능을 가진 자바스크립트 파일을 만들어내는 기능 

노드를 기반으로 기능하기 때문에 노드없이는 사용이 불가능함 

 

4-2

nodejs 설치 및 환경설정 

4-3

터미널이란?

GUI(graphic user interface)

크롬-----(이거 실행해)------>window 

CLI(command line interface)

터미널----(명령어 입력)---->window

 

CLI는 화면에 나타나지 않고 명령만으로 실행이 되기 때문에 편리 

 

 

기존의 javascript는 브라우저의 개발자 도구에서 실행을 확인할 수 있었는데 

node의 경우 터미널 창에서 실행되는 것을 확인 할 수 있음 

 

다른 파일에서 기능을 수행하게 하는 코드 

//calc.js
//계산 기능을 하는 파일
const add = (a, b) => a + b;
const sub = (a, b) => a - b;

//모듈을 내보내야함
module.exports = {
  moduleName: "calc module",
  add: add,
  sub: sub,
};

calc의 모듈을 index에서 수행하게 함

//index.js
const calc = require("./calc");

console.log(calc.add(1, 2));
console.log(calc.add(4, 5));
console.log(calc.add(10, 2));

이러한 것은 common js라고 함

 

4-4

NPM(Node Package Manager): node.js의 패키지 관리 도구 

 

패키지  

누군가 만들어 놓은 기능들을 모아놓은 것 

 

package.json : 패키지에 대한 정보들을 담아 놓은 파일

name, version, description, main, script, test...

 

npm사이트 

무료로 이용할 수 있는 패키지 사이트 

우리가 사용하는 패키지 : randomcolor

-npm install randomcolor를 이용해서 모듈을 설치 

-json에 dependencies가 나타나게 됨

-자동으로 node_module, package-lock.json파일이 생김

-node_module에는 다운받은 randomcolor가 설치되어있고 

-package-lock.json에는 다운받은 파일의 버전들의 정보가 기록되어 있음

 

const randomColor = require('randomColor');를 통해 패키지파일을 불러옴

 

5-1

why react.js ??

첫번째 이유 

중복이 되는 부분에서 문제가 발생: shotgun surgery

공통적으로 사용될것으로 예상되는 것을 모듈로 제작을 함

-작성해야되는 코드의 양이 줄어 듬 

 

기존의 방식으로는 컴포넌트화 하기가 힘듦 

그래서 react가 필요함

v react는 component기반의 UI라이브러리v

레고를 만드는 것처럼 코딩이 가능해짐 

 

두번째 이유 

명령형 프로그래밍(절차를 하나하나 다 나열 해야함) 제이쿼리

--> 선언형 프로그래밍 (그냥 목적을 바로 말함)리액트

 

세번째 이유

virtual dom: 

자바스크립트가 요소를 추가하는 과정에서 생기는 문제를 해결해줌 

 

5-2

boiler plate:

보일러를 찍어내는 틀 

마치 보일러를 찍어내듯이 서비스를 개발할 수 있는 빵틀의 역할을 하는 패키지를 의미함

 

'개발 > React 스터디' 카테고리의 다른 글

리액트 5주차  (0) 2023.05.21
리액트 4주차  (0) 2023.05.07
리액트 3주차  (0) 2023.04.30
리액트 2주차  (0) 2023.04.08

+ Recent posts