더보기
Detail.js

하트

좋아요 1

댓글수 2

기본댓글1 내용

기본댓글2 내용



훅스 useState 



App.js에 Detail.js



state
1 comment 배열 2개
2 likeCount



하트를 클릭하면 좋아요 카운트를 올리고 useEffect를 이용해서 색깔이 변하고

좋아요 수가 2로 변함



나중에 댓글을 쓰면 부모의 state 값을 바꿔야한다

 

 

import React, { useState, useRef, useEffect } from "react";
import emptyimg from "./img/empty_heart.png";
import fillimg from "./img/fill_heart.png";

const Detail = () => {
  const [like, setLike] = useState(0);
  const [count, setCount] = useState(2);
  const [nowImg, setNowImg] = useState(emptyimg);
  const img = useRef();

  useEffect(() => {
    console.log("use");
    img.current.src = nowImg;
  }, [like]);

  const fill = () => {
    setLike(like + 1);
    setNowImg(fillimg);
  };

  return (
    <div>
      <div>
        <img onClick={fill} ref={img} />
      </div>
      <div>좋아요{like}</div>
      <div>댓글수{count}</div>
      <div>댓글1</div>
      <div>댓글2</div>
    </div>
  );
};

export default Detail;

 

 

 

 

참고사항

https://20200302wc.tistory.com/474

 

리액트 숙제

https://github.com/jg20228/ReactHooksHomework import React, { useState, useEffect, useRef } from "react"; import logo2 from "./img/logo2.png"; import logo1 from "./img/logo.jpg"; const Detail2 = ()..

20200302wc.tistory.com

 

'Web > ReactJS' 카테고리의 다른 글

리액트 // redux 리덕스  (0) 2020.08.12
리액트 // useEffect 연습  (0) 2020.08.05
리액트 자동완성 스니펫  (0) 2020.08.04
리액트 // hooks 훅스 / useState / useEffect / useMemo / useRef  (0) 2020.08.03
리액트 // 생명주기  (0) 2020.07.29

 

 

훅스

 

 

자바 - 멤버변수 메소드

자바스크립트 - 함수

 

함수형 프로그래밍

의존성배제

상태가 없다 (즉 멤버변수가 없다)

대신 state 를 넘겨준다 (DB에서 들고온 데이터를 state로 가져온다)

DB + 변수 + 함수파라미터 모두 동기화

 

의존성 배제

엔지니어가 가로등을 고치려면 망치와 사다리가 필요하다고 가정한다

엔지니어는 망치와 사다리에 의존적이다

 

1번가로등 고장 -> 정상

2번가로등 정상

 

이렇게 확인하여 고치는 것이 아니라 저장된 문서(DB)를 이용하여 고장확인을 하는 것

이것이 함수형

 

hooks

{useState}를 임포트해준다

0자리는 오브젝트자리

 

 

 

add 함수 추가

 

 

 

숫자가 증가한다

 

...(정규연산자)는 배열을 for문으로 뿌리는 것이라고 생각하면 됨

 

변경버튼을 누르면 비밀번호만 바뀐다

 

변수가 여러개 필요하다면 여러개 선언하면 된다

 

---------------------

함수형 컴포넌트에서 props 받으려면

괄호에 바로 넣어버리면 된다

---------------------

 

useEffect

클래스형 컴포넌트의 componentDidMount와 같다

 

 

change 함수 생성

 

여러번 눌러도 한번만 변경되고 더이상 변경되지 않는다

 

대괄호가 들어가면 최초실행시에만 콘솔로그가 뜬다

 

눌려도 렌더링 문구가 안뜬다 useEffect (초기화Constructor의 용도로 사용된다)

 

대괄호 안에 name을 넣으면

 

렌더링이 처음 + 이름변경 했을 때 한번 렌더링 문구가 뜬다

 

useEffect는 특정 값이 변경 되었을 때 캐치하고 싶은 경우!

 

숙제 = 용도 생각해보기

 

useReducer는 리덕스를 배워야한다 (상태관리)

 

----------------

 

useMemo (필수!)

axios 같은 것을 받을 때 메모에 저장

연산최적화 (shouldUpdateComponent)

 

자바스크립트의 reduce 는 누적값에 추가값을 더하거나 빼거나 처리

a는 누적값 b는 더할 값

 

e는 컨텍스트

e.target 은 input 태그

 

 

 

 

숫자를 넣을 때마다 평균값을 계산한다

렌더가 실행되면서 값 변한거있는지 찾는다

하지만 list 는 그대로라서 평균값은 그대로

 

값이 변경 되면 리렌더링 되서 괄호가있는 함수

getAverage(list)와

JSX {괄호}안에만 변경이된다

 

-----

 

memoAvg는 list 값이 변경 되었을 때만 실행하는 것

 

 

더보기
import React, { useState, useMemo } from "react";

const getAverage = (numbers) => {
  console.log("평균값 계산 중..");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b); //
  console.log(sum);
  return sum / numbers.length;
};

const App = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");

  //useMemo(실행할함수,[변수,변수])
  const memoAvg = useMemo(() => getAverage(list), [list]);

  const onChange = (e) => {
    setNumber(e.target.value);
  };

  const onInsert = (e) => {
    const nextList = list.concat(parseInt(number));
    setList(nextList);
    setNumber("");
  };

  return (
    <div>
      <input value={number} onChange={onChange} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      평균값: {memoAvg}
    </div>
  );
};

export default App;

 

---

useEffect와 useMemo 차이

useEffect 하나의 일이 발생했을 때 추가적인 일

useMemo 어떤 것이 변경 되었을 때 실행 (걸러주는 것 : 데이터 변경되면 실행 : ex 다운로드)

---------

+ useCallback

----------

ref는 DOM에 접근하는 유일한 방법

key는 해당 태그의 고유한 속성

useRef - 밸리데이션체크

특이한 문법

자바스크립트에서 변수만들 때 변수를 동적으로 만들고 싶을 때 

리액트에서는 값을 변수이름으로 쓸 수 있다 

-------------

 

화면시작하자마자 포커스를 주고 싶다

 

 

 

 

 

콘솔로 확인해보면 쓸 수 있는 속성들이 나온다 

 

 

 

 

커서가 가있고 배경색이 바뀌어 있다

 

 

 

 

'Web > ReactJS' 카테고리의 다른 글

리액트 // 스테이트를 훅스로 바꾸기  (0) 2020.08.05
리액트 자동완성 스니펫  (0) 2020.08.04
리액트 // 생명주기  (0) 2020.07.29
리액트 // axios / 프로미스 / async  (0) 2020.07.28
리액트 // URL파라미터 받기  (0) 2020.07.27

 

라이프 싸이클

 

클래스형 컴포넌트

함수형 컴포넌트 - 생명주기를 다룰 수 없다

 

 

컴포넌트 하나 만들어 준다

 

import React, { Component } from "react";

// 클래스형 컴포넌트
class Counter extends Component {
  state = {
    number: 0,
  };

  // 그림을 그려주는 메서드
  render() {
    // 이 공간은 2가지의 값을 컨트롤 할 수 있다
    const temp1 = this.state;
    const temp2 = this.props;

    return (
      <div>
        <h1>카운터</h1>
        <div>값: {this.state.number}</div>
      </div>
    );
  }
}

export default Counter;

 

const가 있는 것과 없는 것의 차이

데이터 1번만 받고 더 이상 새로운 데이터를 받을 필요가 없을 때 (최초 실행 후 읽기전용) 

 

값이 추후 변경 될 가능성이 있을 경우 const를 뺀다

 

render는 그림을 그려주는 함수 = setState()가 호출되거나, 최초에 객체 생성시 그림 그려줌

render 내부에서는 state와 props에 접근할 수 있음

return 내부는 JSX 문법이 들어감

 

 

import React, { Component } from "react";

// 클래스형 컴포넌트
class Counter extends Component {
  state = {
    number: 0,
  };

  add = () => {
    this.setState({
      number: this.state.number + 1,
    });
  };

  minus = () => {
    this.setState({
      number: this.state.number - 1,
    });
  };

  // 그림을 그려주는 메서드
  //render는 그림을 그려주는 함수 = setState()가 호출되거나, 최초에 객체 생성시 그림 그려줌
  //render 내부에서는 state와 props에 접근할 수 있음
  //return 내부는 JSX 문법이 들어감
  render() {
    // 이 공간은 2가지의 값을 컨트롤 할 수 있다
    // temp1 = this.state;
    // temp2 = this.props;

    return (
      <div>
        <h1>카운터</h1>
        <div>값: {this.state.number}</div>
        <button onClick={this.add}>+</button>
        <button onClick={this.minus}>-</button>
      </div>
    );
  }
}

export default Counter;

 

 

import React, { Component } from "react";
import Counter from "./Counter";

class App extends Component {
  render() {
    return (
      <div>
        <Counter />
      </div>
    );
  }
}

export default App;

 

 

 

----

 

Counter 에서 state 삭제

 

import React, { Component } from "react";

// 클래스형 컴포넌트
class Counter extends Component {
  add = () => {};

  minus = () => {};

  // 그림을 그려주는 메서드
  //render는 그림을 그려주는 함수 = setState()가 호출되거나, 최초에 객체 생성시 그림 그려줌
  //render 내부에서는 state와 props에 접근할 수 있음
  //return 내부는 JSX 문법이 들어감
  render() {
    // 이 공간은 2가지의 값을 컨트롤 할 수 있다
    // temp1 = this.state;
    // temp2 = this.props;

    return (
      <div>
        <h1>카운터</h1>
        <div>값: {this.props.number}</div>
        <button onClick={this.add}>+</button>
        <button onClick={this.minus}>-</button>
      </div>
    );
  }
}

export default Counter;

 

 

App.js 에서 state 추가하고 컴포넌트에 프롭스 넘겨주기

import React, { Component } from "react";
import Counter from "./Counter";

class App extends Component {
  state = {
    number: 0,
  };

  render() {
    return (
      <div>
        <Counter number={this.state.number} />
      </div>
    );
  }
}

export default App;

 

 

 

 

-----------

 

이렇게 사용 합시다!

 

App

import React, { Component } from "react";
import Counter from "./Counter";

class App extends Component {
  state = {
    number: 0,
  };

  add = () => {
    this.setState({
      number: this.state.number + 1,
    });
  };

  minus = () => {
    this.setState({
      number: this.state.number - 1,
    });
  };

  render() {
    return (
      <div>
        <Counter number={this.state.number} add={this.add} minus={this.minus} />
      </div>
    );
  }
}

export default App;

 

 

Counter

import React, { Component } from "react";

// 클래스형 컴포넌트
class Counter extends Component {
  // 그림을 그려주는 메서드
  //render는 그림을 그려주는 함수 = setState()가 호출되거나, 최초에 객체 생성시 그림 그려줌
  //render 내부에서는 state와 props에 접근할 수 있음
  //return 내부는 JSX 문법이 들어감
  render() {
    // 이 공간은 2가지의 값을 컨트롤 할 수 있다
    // temp1 = this.state;
    // temp2 = this.props;

    return (
      <div>
        <h1>카운터</h1>
        <div>값: {this.props.number}</div>
        <button onClick={this.props.add}>+</button>
        <button onClick={this.props.minus}>-</button>
      </div>
    );
  }
}

export default Counter;

 

----------------

 



생성자는 최초에 실행될 때만 호출 되고 값 변경시에는 렌더만 실행된다.

 

 

 

 

 

 

값이 바뀔 때마다 실행됨 (바뀔 때마다 props가 날아오기 때문)

->  함수형컴포넌트에서는 훅스 사용

 

 

 

render 직후 한 번만 호출됨

 

 

-------

 

넘어올 nextProps 와 this.props 를 비교

(아래는 !==일경우 retrun true를 해야한다 주의)

 

false로 설정하였으니 호출은 되나 값은 변경되지 않는다

 

------------------

 

 

 

 

 

 

 

 

 

 

 

https://styled-components.com/docs/basics#installation

 

styled-components: Basics

Get Started with styled-components basics.

styled-components.com

 

 

 

 

 

 

<post key={PK} id={1} title=첫 / >

key는 데이터베이스의 기본키(PK)를 넣자

리액트에 알려줘야한다

기본키를 넣으면 중간에 넣거나 할때 계산이 편하다

반복되는 컴포넌트가 있다면 넣자

 

https://velopert.com/3636

 

누구든지 하는 리액트 7편: 배열 다루기 (1) 생성과 렌더링 | VELOPERT.LOG

이 튜토리얼은 10편으로 이뤄진 시리즈입니다. 이전 / 다음 편을 확인하시려면 목차를 확인하세요. 이번에는 리액트 프로젝트에서 배열을 다루는 방법을 알아보겠습니다. 리액트에서는 배열을

velopert.com

 

 

 

 

액시오스 설치 (통신)

 

 

import React, { Component } from "react";
import Axios from "axios";

class App extends Component {
  state = {
    data: null,
  };

  onClick = () => {
    // 다운받은 json데이터를 자바스크립트 오브젝트로 변환해줌
    Axios.get("https://jsonplaceholder.typicode.com/todos/1") // get방식으로 호출
      // 콜백부분
      .then((resp) => {
        // 프로미스, 밑에꺼 실행하다가 IO가 끝나면 돌아옴
        console.log(resp);
        return;
      });
  };

  render() {
    return (
      <div>
        <h1>클릭하세요</h1>
        <button onClick={this.onClick}>클릭</button>
      </div>
    );
  }
}

export default App;

 

 

 

 

-----------

static default props 검색해보기

-------------

 

프로미스 방식

import React, { Component } from "react";
import Axios from "axios";

class App extends Component {
  state = {
    data: {
      userId: null,
      id: null,
      title: null,
      completed: null,
    },
  };

  onClick = () => {
    const { data } = this.state;
    // 다운받은 json데이터를 자바스크립트 오브젝트로 변환해줌
    Axios.get("https://jsonplaceholder.typicode.com/todos/1") // get방식으로 호출
      // 콜백부분
      .then((resp) => {
        // 프로미스, 밑에꺼 실행하다가 IO가 끝나면 돌아옴
        console.log(resp);
        this.setState({
          data: { data, ...resp.data },
        });
        return;
      });
  };

  render() {
    const { data } = this.state; // 구조분할할당

    return (
      <div>
        <div>아이디: {data.userId}</div>
        <div>제목: {data.title}</div>
        <hr />
        <h1>클릭하세요</h1>
        <button onClick={this.onClick}>클릭</button>
      </div>
    );
  }
}

export default App;

 

 

async 방식

import React, { Component } from "react";
import Axios from "axios";

class App extends Component {
  state = {
    data: {
      userId: null,
      id: null,
      title: null,
      completed: null,
    },
  };

  onClick = async () => {
    const { data } = this.state;
    // 다운받은 json데이터를 자바스크립트 오브젝트로 변환해줌
    let resp = Axios.get("https://jsonplaceholder.typicode.com/todos/1"); // get방식으로 호출
    this.setState({
      data: { data, ...resp.data },
    });
  };

  render() {
    const { data } = this.state; // 구조분할할당

    return (
      <div>
        <div>아이디: {data.userId}</div>
        <div>제목: {data.title}</div>
        <hr />
        <h1>클릭하세요</h1>
        <button onClick={this.onClick}>클릭</button>
      </div>
    );
  }
}

export default App;

 

 

결과

 

--------------

 

 

 

 

참고사이트

함수형

https://pro-self-studier.tistory.com/76

 

1. Route 와 파라미터, 쿼리

안녕하세요, 프로독학러 입니다. 이번 포스팅에서는 리액트 라우터에 대해서 좀 더 자세히 알아보도록 하겠습니다. * 포스팅의 내용은 Velopert 님의 리액트 라우터 강의를 복습한 내용이므로 Velop

pro-self-studier.tistory.com

 

클래스형

https://gongbu-ing.tistory.com/44

 

React | Router : URL로 parameter 전송하기

 이전 포스팅에서 SPA의 한계를 극복하고자 라우터를 이용하여 경로에 알맞은 컴포넌트를 불러오는 방법에 대해 공부했다. React | Router : URL로 페이지 접근하기 Single Page Application(SPA) SPA는 서버로

gongbu-ing.tistory.com

 

 

--------------

 

Nav.js

import React from "react";
import { Link } from "react-router-dom";

const Nav = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/">홈</Link>
        </li>
        <li>
          <Link to="/about/1">어바웃</Link>
        </li>
        <li>
          <Link to="/profile">프로필</Link>
        </li>
      </ul>
    </div>
  );
};

export default Nav;

 

링크를 걸 네비게이션 바에서 /about/1 로 임의로 1을 넘겨주었다

 

 App.js

import React, { Component } from "react";
import Home from "./page/Home";
import About from "./page/About";
import Profile from "./page/Profile";
import Nav from "./components/Nav";
import { Route } from "react-router-dom";

// exact={true} 는 정확히 주소가 맞아야먄 나오도록 할 수 있다.
class App extends Component {
  render() {
    return (
      <div>
        <Nav />
        <hr />
        <Route path="/" component={Home} exact={true} />
        <hr />
        <Route path="/about/:num" component={About} />
        <hr />
        <Route path="/profile" component={Profile} />
      </div>
    );
  }
}

export default App;

 

Route 시킬 component를 About으로 세팅하고, path="/about/:num"과 같이 변수명을 num으로 지정해준다.

 

About.js

import React from "react";

const About = ({match}) => {
  return (
    <div>
      <h1>ABOUT 페이지 입니다. {match.params.num}</h1>
    </div>
  );
};

export default About;

 

About 함수형 컴포넌트에서 매개변수에 {match}를 적어주고 리턴할 내용에 {match.params.변수명}을 적어주면 입력된다.

 

+ Recent posts