풀 스택 React 및 Node.js - 양식 추가

React 클라이언트 사이트에 양식 추가



데이터에서 양식을 생성하기 위해 여기에 몇 가지 구성 요소를 추가할 것입니다. 나중에 살펴보겠지만 지금은 직접 작성하겠습니다.

React 프로젝트의 src 폴더 아래에 다음 파일을 모두 만드세요!

Input.js를 만들고 다음 코드를 붙여넣습니다.

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

const Input = ({
id, value = "", type = "text", readOnly = false, required = false
}) => {
  const input = useRef(null);

  useEffect(() => {
    if (input.current) {
      const sValue = value.toString();

      if (type === 'checkbox') {
        input.current.checked = sValue === 'true';
        input.current.value = 'true'
      } else {
        input.current.value = sValue
      }
    }
  }, [type, value])

  return (
    <input
      ref={input}
      id={id}
      name={id}
      type={type}
      readOnly={readOnly}
      disabled={readOnly}
      required={required}
    />
  );
};

export default Input;


With useEffect and useRef hooks you can be certain that your uncontrolled inputs will update when the value prop changes.



Input.js는 값 매개변수의 데이터 유형에 따라 텍스트 입력 또는 체크박스를 생성합니다. 다음으로 Input.js로 레이블을 렌더링하는 구성 요소가 필요합니다.

React has two kinds of inputs: controlled and uncontrolled. With controlled the value is managed by React in useState. With uncontrolled the value is managed by the DOM. The difference is what the "single source of truth" is. Controlled are ideal when you have a small number of inputs. Uncontrolled perform better and, when your controls are inside a form, it's easier to have a single form event handler rather than an event handler on each input.



다음과 같이 InputLabel.js를 만듭니다.

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

const InputLabel = ({label, error, info, ...inputProps}) => {
    return (
        <p
            className="input-label"
        >
            <label htmlFor={inputProps.id}>
                {
                    label
                }
            </label>
            <Input
                {...inputProps}
            />
        </p>
    );
};

export default InputLabel;


이제 "입력"구성 요소를 사용하여 개체를 여러 양식 필드로 전환하는 일부 문자열 유틸리티 기능이 있는 양식 구성 요소를 만듭니다.

Form.js 만들기:

import React from 'react';
import InputLabel from "./InputLabel";
import './form.css'

const isNullOrUndefined = prop => prop === null
    || prop === undefined;
const isEmptyString = prop => isNullOrUndefined(prop)
    || prop === '';
const capitalize = word =>
    word.charAt(0).toUpperCase() +
    word.slice(1).toLowerCase();

function titleFromName(name) {
    if (isEmptyString(name)) {
        return '';
    }

    return name.split(/(?=[A-Z])|\s/).map(s => capitalize(s)).join(' ')
}

const Form = ({entity}) => {
  return (
    <form>
      {
        Object.entries(entity).map(([entityKey, entityValue]) => {
          if (entityKey === "id") {
            return <input
              type="hidden"
              name="id"
              key="id"
              value={entityValue}
            />
          } else {
            return <InputLabel
              id={entityKey}
              key={entityKey}
              label={titleFromName(entityKey)}
              type={
                typeof entityValue === "boolean"
                  ? "checkbox"
                  : "text"
                }
                value={entityValue}
              />
            }
          })
        }
      <button
        type="submit"
      >
        Submit
      </button>
    </form>
  );
};

export default Form;



그리고 form.css를 만듭니다.

form {
    padding: 1em;
    background: #f9f9f9;
    border: 1px solid #c1c1c1;
    margin: 2rem auto 0 auto;
    max-width: 600px;
}

form button[type=submit] {
    margin-left: 159px;
}

.input-label {
    display: flex;
}

.input-label label {
    font-weight: bold;
}

.input-label input {
    margin-left: 12px;
}

@media (min-width: 400px) {
    label {
        text-align: right;
        flex: 1;
    }

    input,
    button {
        flex: 3;
    }
}


이제 Form.js 구성 요소를 사용하도록 AddEditNote.js를 변경합니다.

import React from 'react';
import Form from './Form';

const noteEntity = {
    id: 1,
    title: 'A Note',
    content: 'Lorem ipsum dolor sit amet',
    author: 'neohed',
    lang: 'en',
    isLive: true,
    category: '',
}

const AddEditNote = () => {
    return (
        <div>
            <Form
                entity={noteEntity}
            />
        </div>
    );
};

export default AddEditNote;


이를 테스트하려면 node-react-stack/react-client 폴더 내에서 다음을 실행하세요.

npm run start


noteEntity 객체의 값이 포함된 HTML 양식이 표시되어야 합니다.

이제 앱에서 어떤 데이터를 사용하는지 쉽게 확인할 수 있도록 "디버그"구성 요소를 만들 것입니다. 다음과 같이 새 파일인 RenderData.js를 만듭니다.

import React from 'react';
import './render-data.css'

const RenderData = ({data}) => {
    return (
        <div
            className='render-data'
        >
          <pre>
            {
                JSON.stringify(data, null, 3)
            }
          </pre>
        </div>
    );
};

export default RenderData;


render-data.css 만들기:

@import url('https://fonts.googleapis.com/css2?family=Fira+Code&display=swap');

.render-data > pre {
    font-family: 'Fira Code', monospace;
    font-size: 1.2em;
    padding: 8px 0 0 32px;
}


Fira Code is a nice monospace font provided by google. Monospace fonts are ideal for displaying code or data.



마지막으로 다음과 같이 AddEditNote.js를 편집합니다.

import React from 'react';
import RenderData from "./RenderData";
import Form from './Form';

const noteEntity = {
    id: 1,
    title: 'A Note',
    content: 'Lorem ipsum dolor sit amet',
    author: 'neohed',
    lang: 'en',
    isLive: true,
    category: '',
}

const AddEditNote = () => {
    return (
        <div>
            <RenderData
                data={noteEntity}
            />
            <Form
                entity={noteEntity}
            />
        </div>
    );
};

export default AddEditNote;


지금 React 앱을 실행하면 다음과 같은 화면이 표시됩니다.


console.log 객체만 noteEntity 할 수 있지만, 때로는 이와 같은 구성 요소를 사용하여 브라우저 창에서 객체를 렌더링할 때 이해하기가 더 쉽습니다.

다음에 우리는 ...

코드 저장소: Github Repository

좋은 웹페이지 즐겨찾기