React 2.

AWESOMee·2022년 6월 30일
0

React

목록 보기
2/6
post-thumbnail

UseEffect

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

const UseEffect = () => {
  const [name, setName] = useState("");
  const [nickname, setNickname] = useState("");
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("name, nickname 값이 업데이트될 때마다 실행");
    console.log({
      name,
      nickname,
    });
    setCount(count + 1)
  }, 
//   []  어떤 값에 업데이트 상태에 따라서 실행될 것인지 결정
  [name, nickname]
  );

  const changeName = (e) => {
    setName(e.target.value);
  };

  const changeNickname = (e) => {
    setNickname(e.target.value);
  };

  return (
    <div>
      <input value={name} onChange={changeName}></input>
      <input value={nickname} onChange={changeNickname}></input>
      <br />
      <b>이름: {name}</b>
      <br />
      <b>별명: {nickname}</b>
      <br />
      <b>렌더링 횟수는: {count}</b>
    </div>
  );
};

export default UseEffect;

useReducer

import React, { useReducer } from "react";

function reducer(state, action) {
  // reducer function은 action.type에 따라 동작을 정의할 수 있음
  // useReducer는 action.type을 정의하지 않아도 됨
  // 리덕스의 리듀서는 action.type을 반드시 정의해야 함
  switch (action.type) {
    case "INCREASE":
      return { value: state.value + 1 };
    case "DECREASE":
      return { value: state.value - 1 };
    default:
      return state;
  }
}

const UseReducer = () => {
  const [state, dispatch] = useReducer(reducer, { value: 0 });
  return (
    <div>
      <p>현재 값은 {state.value}입니다.</p>
      <button onClick={() => dispatch({ type: "INCREASE" })}>+1</button>
      <button onClick={() => dispatch({ type: "DECREASE" })}>-1</button>
    </div>
  );
};

export default UseReducer;

Average 구하기

import React, { useState } from "react";

const getAverage = (numbers) => {
  console.log("평균 값 계산중...");
  if (numbers.length === 0) return 0;
  let sum = 0;
  numbers.forEach((element) => {
    sum += element;
  })
  return sum / numbers.length;
};

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

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

  const handleClick = (e) => {
    const nextList = list.concat(parseInt(number));
    setList(nextList);
    setNumber("");
  };
  return (
    <div>
      <input type="text" value={number} onChange={handleChange} />
      <button onClick={handleClick}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>평균 값: {getAverage(list)}</b>
      </div>
    </div>
  );
};

export default Average;

useMemo

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

const getAverage = (numbers) => {
  console.log("평균 값 계산중...");
  if (numbers.length === 0) return 0;
  let sum = 0;
  numbers.forEach((element) => {
    sum += element;
  });
  return sum / numbers.length;
};

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

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

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

  const avg = useMemo(() => getAverage(list), [list]);
  return (
    <div>
      <input type="text" value={number} onChange={handleChange} />
      <button onClick={handleClick}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>평균 값: {avg}</b>
      </div>
    </div>
  );
};

export default AverageUseMemo;

useCallback

import React, { useCallback, useMemo, useState } from "react";

const getAverage = (numbers) => {
  console.log("평균 값 계산중...");
  if (numbers.length === 0) return 0;
  let sum = 0;
  numbers.forEach((element) => {
    sum += element;
  });
  return sum / numbers.length;
};

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

  const handleChange = useCallback((e) => {
    console.log("체인지함수 생성");
    setNumber(e.target.value);
  }, []);

  const handleClick = useCallback(
    (e) => {
      console.log("클릭함수 생성");
      const nextList = list.concat(parseInt(number));
      setList(nextList);
      setNumber("");
    },
    [number, list]
  );

  const avg = useMemo(() => getAverage(list), [list]);
  return (
    <div>
      <input type="text" value={number} onChange={handleChange} />
      <button onClick={handleClick}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>
        <b>평균 값: {avg}</b>
      </div>
    </div>
  );
};

export default AverageUseCallback;

custom hooks

useInput.js

import { useReducer } from "react";

function reducer(state, action) {
  return {
    ...state,
    [action.name]: action.value,
  };
}

export default function useInput(initialForm) {
  const [state, dispatch] = useReducer(reducer, initialForm);

  const handleChange = (e) => {
    dispatch(e.target);
  };

  return [state, handleChange];
}

CustomHooks.js

import React from "react";
import useInput from "./useInput";


const CustomHooks = () => {
  const [state, handleChange] = useInput({
    name: "",
    nickname: "",
  });

  const { name, nickname } = state;

  return (
    <div>
      <input type="text" name="name" value={name} onChange={handleChange} />
      <input
        type="text"
        name="nickname"
        value={nickname}
        onChange={handleChange}
      />
      <br />
      <b>이름: {name}</b>
      <br />
      <b>별명: {nickname}</b>
    </div>
  );
};

export default CustomHooks;
;

component styling

CSS Module

CSSModule.module.css

.wrapper {
    background-color: black;
    padding: 1rem;
    color: white;
    font-size: 2rem;
}

.inverted {
    color: black;
    background-color: white;
    border: 1px solid black;
}

/* write global class */
:global .something {
    font-weight: bold;
    color: aqua;
}

CSSModule.js

import React from 'react';
import styles from '../cssmodule/CSSModule.module.css'

const CSSModule = () => {
    return (
        <>
        <div className={`${styles.wrapper} ${styles.inverted}`}>
            hello. <span className='something'>CSSModule</span>
        </div>
        <div className={styles.wrapper}>
            hello. <span className='something'>CSSModule</span>
        </div>
        <div className={styles.wrapper}>
            hello. <span className='something'>CSSModule</span>
        </div>
        </>
    );
};

export default CSSModule;

'npm install sass'

SassComponent.scss

// modifying scss, server rebooting is necessary
@import './utils.scss';

.SassComponent {
    display: flex;
    .box {
        background-color: $red;
        cursor: pointer;
        transition: all 0.3s ease-in;

        // using .box, .red at the same time
        &.red {
            background-color: $red;
            @include square(1);
        }

        &.orange {
            background-color: $orange;
            @include square(2);
        }

        &.yellow {
            background-color: $yellow;
            @include square(3);
        }

        &.green {
            background-color: $green;
            @include square(4);
        }

        &.blue {
            background-color: $blue;
            @include square(5);
        }

        &.indigo {
            background-color: $indigo;
            @include square(6);
        }

        &.violet {
            background-color: $violet;
            @include square(7);
        }

        // .box:hover
        &:hover {
            background-color: black;
        }
    }
}

utils.scss

// declare variables
$red: #fa5252;
$orange: #df7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$indigo: #5c7cfa;
$violet: #7950f2;

// create mixin(use reusable style-block as function)
@mixin square($size) {
    $calculated: 32px * $size;
    width: $calculated;
    height: $calculated;
}

ScssComponent.js

import React from 'react';
import '../scss/SassComponent.scss';

const SassComponent = () => {
    return (
        <div className='SassComponent'>
            <div className='box red'></div>
            <div className='box orange'></div>
            <div className='box yellow'></div>
            <div className='box green'></div>
            <div className='box blue'></div>
            <div className='box indigo'></div>
            <div className='box violet'></div>
        </div>
    );
};

export default SassComponent;

'npm install styled-component'

StyledComponent.js

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

const Box = styled.div`
  background: ${(props) => props.color || "blue"};
  padding: 1rem;
  display: flex;
  width: 600px;
  margin: 0 auto;
  @media (max-width: 800px) {
    width: 500px;
  }
  @media (max-width: 600px) {
    width: 400px;
  }
  @media (max-width: 400px) {
    width: 300px;
  }
`;

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

  &:hover {
    background: rgba(255, 255, 255, 0.9);
  }

  ${(props) =>
    props.inverted &&
    css`
      background: none;
      border: 2px solid white;
      color: white;

      &:hover {
        background: white;
        color: black;
      }
    `}

    & + button {
        margin-left: 1rem;
    }
`;

const StyledComponent = () => {
  return (
    <Box color="black">
        <Button>hello</Button>
        <Button inverted={true}>border only</Button>
    </Box>
  );
};

export default StyledComponent;
profile
개발을 배우는 듯 하면서도

0개의 댓글