[React] input안에 value 복사하는 버튼만들기

Miog Yang·2022년 12월 13일

오늘의 개발 기록

  1. 서비스아이디 등록시 웹과 앱의 선택에 따라 앱의 경우 서버에서 서비스 키를 받는다.
  2. 받은 서비스 키의 Default값을 hide로 하고 필요시 키가 보이게 만든다.
  3. 복사 버튼을 생성하여 클릭시 해당 서비스 키를 복사한다.

먼저 노션에 수정된 키와 값을 확인하여 수정

  • web : 0, app:1로 지정하여 serviec가 1일경우 서비스키를 받는다.
//등록부분

//1. 초기값은 빈값으로 고정
const initFormValues = {
  domain: '', memo: '', service: ''
};
//2. state지정.
const [formValues, setFormValues] = useState(initFormValues);

//3. handler : input에 들어가는 value
const handleFormChange = (e) => {
    setFormValues(prev => ({ ...prev, [e.target.name]: e.target.value }));
  };
//해당 input에 onChange이벤트와 함께 value=formValues.key

//4. handler : checkbox
const handleRadioChange = (name, value) => {
  setFormValues(prev => ({ ...prev, [name]: value }));
};

<PopupFormRow title="WEB / APP 서비스 이용<em>*</em>">
  <FormRadioWrap>
    <FormCheck theme="radio" name="service" value="0" checked={formValues.service === '0'} onChange={handleRadioChange}>
                    WEB
    </FormCheck>
    <FormCheck theme="radio" name="service" value="1" checked={formValues.service === '1'} onChange={handleRadioChange}>
                    APP
    </FormCheck>
  </FormRadioWrap>
</PopupFormRow>
<CardView>
  
//  ... map()을 사용하여 데이터를 뿌려준다.
<>
    ...

  <CardItem title="Service">
    {d.service === '1' ? 'APP' : 'WEB'}
  </CardItem>

  <CardItem title="Sevice Key" theme="full">
    {<ServiceKey keyValue={d.service_key} /> || '-'}
    //ServiceKey 컴포넌트 생성 데이터 props로 담기
  </CardItem>

</>
  • 해당 서비스 키를 받는 ui는 따로 컴포넌트화하여 작업하고 service_key를 props로 받는다.
//componenets/card/ServiceKey.js

//1. props로 받은 데이터를 input value로 담는다.
const ServiceKey = ({ keyValue }) => {
  //서비스키 hide icon상태
  const [hideKey, setHideKey] = useState(true);
  //서비스키 복사 icon상태
  const [copyBtn, setCopyBtn] = useState(true);
  //복사될 input의 현재값을 받기위해 useRef를 사용
  const keyInput = useRef();
  
  //서비스키 숨기기
  const handleKey = () => {
    setHideKey(!hideKey);
  };
  
  //복사아이콘 
  const handleCopyIcon = () => {
    setCopyBtn(false);
  };

  //복사버튼의 onClick 이벤트
  const handleCopy = () => {
    const el = keyInput.current;
    el.select(); //현재값 선택
    document.execCommand('copy'); //값 복사하기
    handleCopyIcon();
  };
  return (
    <>
      <KeyWrap>
        <input type={hideKey ? 'password' : 'text'} ref={keyInput} value={keyValue} readOnly />
        {hideKey === true ? <RxEyeOpen onClick={handleKey} /> : <RxEyeClosed onClick={handleKey} />}
        {copyBtn === true ? <AiOutlineCopy onClick={handleCopy} /> : <TbCheck onClick={handleCopyIcon} />}
        {copyBtn === true ? <span /> : <span>Service-key copied!</span>}
      </KeyWrap>
    </>
  );
};
export default ServiceKey;

<input type={hideKey ? 'password' : 'text'} ref={keyInput} value={keyValue} readOnly />

  • type : state 상태에 따라 password 또는 text로 변경
    password : *표로 나타남
    text : 서비스 키가 나타남

  • ref : onChange와 같이 현재값을 담기위해 사용한 useRef를 담는다.

  • value : props로 받아온 서비스키를 받아옴

  • readOnly : 에러 "You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly." 해결

You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly.

  • onChange가 없는 상태에서 valueprops 또는 checked prop를 사용한 경우 발생하는 에러
    수정시 defaultValue를 사용하고 수정하지 않을경우 onChange 또는 readOnly를 설정

📌 ref : 참고 블로그

{hideKey === true ? <보기아이콘 onClick={handleKey} /> : <숨기기아이콘 onClick={handleKey} />}
: hideKey가 true일 경우 password 타입이므로 보기아이콘,
false일 경우 text타입이므로 숨기기아이콘으로 변경되게 삼항연산자를 사용한다.

{copyBtn === true ? <복사아이콘 onClick={handleCopy} /> : <체크아이콘 onClick={handleCopyIcon} />}
: 복사아이콘을 클릭하면 체크아이콘으로 변경, 체크아이콘으로 변경시 더는 변경안되게 false로 지정

{copyBtn === true ? : <>Service-key copied!</>}
: 복사아이콘 클릭하여 true로 변경되면 아이콘이 체크로 변경되고 Service-key copied!가 나온다.

🚧 input type이 password로 바뀌어도 *표가 나오는 것이 아닌 빈칸으로 나오는 경우

폰트의 문제
input태그에 폰트를 기본폰트로 변경해준다.

font-family:"Nanum Gothic", sans-serif !important;

💡 버튼을 클릭하여 데이터 복사

//onClick이벤트에 사용할 handler

const handleCopy = () => {
    const el = keyInput.current;
    el.select();
    document.execCommand('copy'); 
  };

const el = keyInput.current;
:useRef로 만든 keyInput의 현재값을 element로 지정
현재값을 선택하는 select()함수 사용
복사하는 document.execCommand('copy')함수 사용
📌 ref execCommand함수 MDN




마치며

처음으로 수정해본 작업이였다. 기존의 사용했던 필요없는 데이터의 키를 사용할 키로 변경하고 데이터값을 수정하였다. 추가로 복사하는 버튼을 만들어 보았다.
el.select() 해당 element를 선택하고 document.execCommand('copy') 복사한다.
다음에 사용할 기회가 또 있을 것 같으므로 기록해보았다.

profile
주니어 개발사전 & 프론트엔드 도전기

0개의 댓글