REACT

calculator contextapi

kimjiwon506 2023. 3. 28. 11:17

calculator contextapi 사용하기 

폴더구조

context > calculator.js

import { createContext, useState, useRef } from "react";

1. react패키지 createContext를 사용해 context생성
const CalculatorContext = createContext({
    state: { inputValue: '', buttonArray: [] },
    actions: { calculate: () => {} }
})

2. calculatorProvider 생성 contextProvider에는 하나의 value값으로 하나의 객체만 들어갈 수 있다.
const CalculatorProvider = ({ children }) => {
    // 연산자 클릭시 전환될 수 있도록 한다. 화면에 보이면 state, 안보이면 ref
    const shouldSetNumberRef = useRef(false);
    // 이전값을 담을 수 있도록 한다.
    const prevNumberRef = useRef(null);
    const [ inputValue, setInputValue ] = useState('')
    const [ calc , setCalc ] = useState({
        inputValue: '0',
        buttonArray: [
          { text: "C", id:"reset", background: "#A29D95", color: "#111111" },
          { text: "+/-", id:"", background: "#A29D95", color: "#111111" },
          { text: "%", id:"percent", background: "#A29D95", color: "#111111" },
          { text: "÷", id:"divide", background: "#FFB039", color: "#ffffff", type: "operator" },
          { text: "7", id:"seven", background: "#484242", color: "#ffffff", type: "number" },
          { text: "8", id:"eight", background: "#484242", color: "#ffffff", type: "number" },
          { text: "9", id:"nine", background: "#484242", color: "#ffffff", type: "number" },
          { text: "x", id:"multiply",background: "#FFB039", color: "#ffffff", type: "operator" },
          { text: "4", id:"four", background: "#484242", color: "#ffffff", type: "number" },
          { text: "5", id:"five",background: "#484242", color: "#ffffff", type: "number" },
          { text: "6", id:"six",background: "#484242", color: "#ffffff", type: "number" },
          { text: "-", id:"minus",background: "#FFB039", color: "#ffffff", type: "operator" },
          { text: "1", id:"one",background: "#484242", color: "#ffffff", type: "number" },
          { text: "2", id:"two",background: "#484242", color: "#ffffff", type: "number" },
          { text: "3", id:"three",background: "#484242", color: "#ffffff", type: "number" },
          { text: "+", id:"plus",background: "#FFB039", color: "#ffffff", type: "operator" },
          { text: "0", id:"zero",background: "#484242", color: "#ffffff", type: "number" },
          { text: ".", id:"comma",background: "#484242", color: "#ffffff", type: "number" },
          { text: "=", id:"equal",background: "#FFB039", color: "#ffffff", type: "operator" }
        ]
    })

    const value = { inputValue, setInputValue, calc, setCalc, shouldSetNumberRef, prevNumberRef }
    
    return (
        <CalculatorContext.Provider value={value} >{children}</CalculatorContext.Provider>
    )
}

export { CalculatorContext }
export default CalculatorProvider

calculator.js

- 우선 더하기 까지만 되도록 구현

import React from 'react';
import * as Styled from './styled';

import { useContext } from 'react';
import { CalculatorContext } from '../../context/calculator';

import Button from './../Button/index';
import Input from './../Input/index';

function Calculator() {
	//useContext를 사용해서 만들어둔 value를 꺼내서 사용한다.
    const { calc, setCalc, shouldSetNumberRef, prevNumberRef } = useContext(CalculatorContext);

    const onClick = (item) => {
      if(item.type === "number") {
        setCalc((prev) => { 
          const inputValue = shouldSetNumberRef.current ? item.text :  prev.inputValue.replace(/(^0+)/, "") + item.text;
          shouldSetNumberRef.current = false;
          return {
            ...calc,
            inputValue
          }
        })
      }
        if(item.type === "operator") {
        switch(item.text){
            case "+" : 
            prevNumberRef.current = Number(prevNumberRef.current) + Number(calc.inputValue);
            shouldSetNumberRef.current = true;
            setCalc({...calc, inputValue: prevNumberRef.current});
        }
        }
    }

    return (
        <Styled._Container> 
            <Styled._Wrap>  
                <Input calc={calc} />
                <Styled._ButtonWrap>
                    {calc.buttonArray.map((item, index) => <Button item={item} index={index} onClick={()=>onClick(item)} />)}
                </Styled._ButtonWrap>
            </Styled._Wrap>
        </Styled._Container>
    );
}

export default Calculator;

https://github.com/kimjiwon506/calculator-context