221202(금)

김민석·2022년 12월 2일
0

Today I Learned

목록 보기
9/30
post-custom-banner

오전

리엑트 데이터 처리

src/App.js

export let StockContext = createContext()  // 1.컨텍스트 만들고

<Route path='/detail/:id' element={
	<StockContext.Provider value={{stock}}>
		<Detail shrits={shrits} />
	</stockContext.Provider>
}/>

src/component/Detail.js

import { StockContext } from '../App'

function Detail(props) {
  let {stock} = useContext(StockContext);

이렇게 해서 전역변수처럼 쓸 수 있다.

데이터처리 예제

src/component/Cart.js



redux

설치

npm install @reduxjs/toolkit react-redux

세팅

src/index.js

import store from './store.js'
import { Provider } from 'react';
root.render(
  <Provider store = {store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>
);

예시

src/component/Store.js // 앞으로 데이터들을 담아 둘 저장 공간

import { configureStore, createSlice} from "@reduxjs/toolkit"
let user = createSlice({
    name : 'user',
    initialState : 'Lee'
})
let stock = createSlice({
    name : 'stock',
    initialState : [1,13,20]
})
export default configureStore({
    reducer : {
            user: user.reducer,
            stock : stock.reducer
    }
})

src/component/Cart.js // 사용할 곳

import {useSelector} from "react-redux";
function Cart() {

  let state = useSelector((state)=>{return state});
console.log(state);

결과 :

오후

redux

함수

store.js

import { configureStore, createSlice } from "@reduxjs/toolkit"

let user = createSlice({
    name : 'user',
    initialState : 'Lee',
    reducers: {
        changeName(state) { 
        //'yuna' + state
        return {state.name = 'kang'}
        },
        userNameChange(state){
        	// return "string + state
            return state.name = 'Lee'
        }
        increase(state){
  			state.age += 1
		}
    }
    //state 수정하길 원하는 함수 작성한다.
})

export let { changeName , userNameChange, increase} =  user.actions

Cart.js

import { changeName } from "../store";
    let state = useSelector((state) => state )
    let dispatch = useDispatch();

배열

추가학습

p415 // 단, 18버전 툴킷? 이라는 새로운 방법을 고려한다.


혼자공부

라이프 사이클의 이해 - 메소드

접두사에 따라

WILL : 작업 전
Did : 작업 작동 후

상태에따라

마운트 : 페이지에 컴포넌트가 나타남

마운트 순서 : constructor->getDerivedStateFromProps->render->componentDidMount
constructor: 클래스 생성자 메서드
getDerivedStateFromProps: props에 있는 값을 state에 넣을 때 사용  
render : 우리가 준비한 UI를 렌더링
componentDidMount : 컴포넌트가 웹 브라우저 상에 나타난 후 호출

업데이트 : 컴포넌트 정보를 업데이트

props,state가 바뀔때
부모 컴포넌트가 리렌더링될 때
this.forceUpdate로 강제 렌더링을 트리거할 때

언마운트 : 페이지에서 컴포넌트가 사라짐


실습 분석

src/LifeCycleSample.js

BEFORE 렌더링

//부모로부터 받은 color 값을 state에 동기화
  static getDerivedStateFromProps(nextProps, prevState) { 
    console.log('getDerivedStateFromProps');
    if (nextProps.color !== prevState.color) {
      return { color: nextProps.color };
    }
    return null;
  }

SET 렌더링

//컴포넌트의 리렌더링을 할지 안할지 결정하는 함수
//여기서는 state.number의 마지막 자리수가 4면 리렌더링을 취소  
shouldComponentUpdate(nextProps, nextState) { 
    console.log('shouldComponentUpdate', nextProps, nextState);
    // 숫자의 마지막 자리가 4면 리렌더링하지 않습니다.
    return nextState.number % 10 !== 4;
  }

AFTER 렌더링

//컴포넌트 변화를 DOM에 보여주기 바로 직전에 호출하는 메소드
//여기서는 변화 직전의 색상속성을 snapshot값으로 반환하여 componentDidUpdate에서 조회할 수 있게 한다
  getSnapshotBeforeUpdate(prevProps, prevState) { 
    console.log('getSnapshotBeforeUpdate');
    if (prevProps.color !== this.props.color) {
      return this.myRef.style.color;
    }
    return null;
  }
//컴포넌트의 업데이트 작업이 끝난 후 호출되는 함수, 
//여기서는 업데이트 직전의 색상을 저장한 스냅샷을 콘솔로그에 보여주고있다.
  componentDidUpdate(prevProps, prevState, snapshot) { //변화직전의 속성값을 조회가능
    console.log('componentDidUpdate', prevProps, prevState);
    if (snapshot) {
      console.log('업데이트되기 직전 색상: ', snapshot);
    }
  }


라이프 사이클의 이해 - ErrorBoundary

사용법

src/ErrorBoundary.js

import React, { Component } from 'react';

class ErrorBoundary extends Component {
  state = {
    error: false
  };
  componentDidCatch(error, info) {
    this.setState({
      error: true
    });
    console.log({ error, info });
  }
  render() {
    if (this.state.error) return <div>에러가 발생했습니다!</div>;
    return this.props.children;
  }
}

export default ErrorBoundary;

src/App.js

//에러가 날 법한 곳을 <ErrorBoundary>로 감싸준다
import ErrorBoundary from './ErrorBoundary';
<ErrorBoundary>
	<LifeCycleSample color={this.state.color} />
</ErrorBoundary>

결과 : 흰 화면이 아닌 에러발생 문구를 사용자에게 알려준다.


컴포넌트 스타일링

CSS Selector

css 클래스가 특정 클래스 내부에 있는 경우에만 스타일을 적용 시킬 수 있다.
예를 들어 .App 안에 들어있는 .logo에 스타일을 적용하고 싶다면 다음과 같이 작성한다

.App .logo{
	animation: App-logo-spin infinite 20s linear;
    heigh: 40vmin;
}

Sass 사용하기

법적으로 매우 멋진 스타일시트라는 뜻으로, 복잡한 작업을 쉽게, 코드 재활용, 가독성 ---> 유지보수 쉽게

설치
React 프로젝트에 Router 설치 방법
1. 터미널을 킨다.
2. Sass 설치를 희망하는 React프로젝트의 디렉토리로 이동한다.
3. npm install node-sass --save 입력한다.
4. 설치한 React 프로젝트 디렉토리를 열어 package.json 파일에 "dependencies" 중 "node-sass" 이 있는지 확인해 본다.

에러가 있다면 이전 설치 참고해서 nodejs버전과 npm 버전을 체크하고
yarn으로 설치를 추천한다.
https://velog.io/@meat7238/221124
yarn add sass

`SassComponent

.SassComponent {
  display: flex;
  background: $oc-gray-2;
  @include media("<768px") {
    background: $oc-gray-9;
  }
  .box {
    background: red; // 일반 CSS 에선 .SassComponent .box 와 마찬가지
    cursor: pointer;
    transition: all 0.3s ease-in;
    &.red {
      // .red 클래스가 .box 와 함께 사용 됐을 때
      background: $red;
      @include square(1);
    }
    &.orange {
      background: $orange;
      @include square(2);
    }
    &.yellow {
      background: $yellow;
      @include square(3);
    }
    &.green {
      background: $green;
      @include square(4);
    }
    &.blue {
      background: $blue;
      @include square(5);
    }
    &.indigo {
      background: $indigo;
      @include square(6);
    }
    &.violet {
      background: $violet;
      @include square(7);
    }
    &:hover {
      // .box 에 마우스 올렸을 때
      background: black;
    }
  }
}

utils.scss

@import '~include-media/dist/include-media';
@import '~open-color/open-color';

// 변수 사용하기
$red: #fa5252;
$orange: #fd7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$indigo: #5c7cfa;
$violet: #7950f2;

// 믹스인 만들기 (재사용되는 스타일 블록을 함수처럼 사용 할 수 있음)
@mixin square($size) {
  $calculated: 32px * $size;
  width: $calculated;
  height: $calculated;
}

classnames

p236

style-components

자바스크립트 하나에 스타일까지 작성할 수 있는 이점이 있다.

설치

yarn add styled-componets
npm install styled-components 

src/StyledComponents.js

import React from 'react';
import styled, { css } from 'styled-components';

const sizes = {
  desktop: 1024,
  tablet: 768
};

// 위에있는 size 객체에 따라 자동으로 media 쿼리 함수를 만들어줍니다.
// 참고: https://www.styled-components.com/docs/advanced#media-templates
const media = Object.keys(sizes).reduce((acc, label) => {
  acc[label] = (...args) => css`
    @media (max-width: ${sizes[label] / 16}em) {
      ${css(...args)};
    }
  `;

  return acc;
}, {});

const Box = styled.div`
  /* props 로 넣어준 값을 직접 전달해줄 수 있습니다. */
  background: ${props => props.color || 'blue'};
  padding: 1rem;
  display: flex;
  width: 1024px;
  margin: 0 auto;
  ${media.desktop`width: 768px;`}
  ${media.tablet`width: 100%;`};
`;

const Button = styled.button`
  background: white;
  color: black;
  border-radius: 4px;
  padding: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font-size: 1rem;
  font-weight: 600;

  /* & 문자를 사용하여 Sass 처럼 자기 자신 선택 가능 */
  &:hover {
    background: rgba(255, 255, 255, 0.9);
  }

  /* 다음 코드는 inverted 값이 true 일 때 특정 스타일을 부여해줍니다. */
  ${props =>
    props.inverted &&
    css`
      background: none;
      border: 2px solid white;
      color: white;
      &:hover {
        background: white;
        color: black;
      }
    `};
  & + button {
    margin-left: 1rem;
  }
`;

const StyledComponent = () => (
  <Box color="black">
    <Button>안녕하세요</Button>
    <Button inverted={true}>테두리만</Button>
  </Box>
);

export default StyledComponent;

src/App.js

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

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

export default App;

결과 :

!! vsCode에 vscode-styled-components 추가 설치해두면 js안에서도 css 색상이 정상적으로 입력된다

Tagged 템플릿 리터럴

백틱 사의의 객체나 함수는 일반적으로 형태를 잃어버린다
`hello ${{foo: 'bar}} ${() => 'world'}!`
결과> "hello object Object => 'world'!"

하지만 Tagged 템플릿 리터럴을 쓰면 값이 출력된다.

스타일링된 엘리먼트 만들기

import styled from 'styled-components';

const MyComponent = styled.div`
	font-size: 2rem;
    `;
const MyInput = styled('input')`
	background: gray;
`
const StyledLink = styled(Link)`
	color: blue;
`

결과>div로 이루어진 리액트 컴포넌트가 생성된다. 나중에 Hello처럼 쓸 수 있다.

input이나 button에 스타일링을 하고 싶다면 styled.button 등으로 넣으면 된다.
유동적이거나 특정 컴포넌트의 경우에도 위와 같은 형태로 구현할 수 있다.

스타일컴포넌트의 스타일에 변수로 넣어준 값을 직접 전달 해 줄 수 있다

const Box = styled.div`
background: ${props => props.color || 'blue'};
padding: 1rem;
display: flex;
`

=>props를 조회해서 props.color의 값을 사용하게 함

profile
뉴비개발자
post-custom-banner

0개의 댓글