NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    JavaScript React+Typescript - 서로 의존하는 드롭다운리스트. (Select relationships)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 일반적인 웹 환경에서 아이템 항목이 의존성을 가지는 경우는 그렇게 흔하지는 않습니다만... 은근히 많이 사용되기도 합니다. 전통적인 웹개발 환경에서는 쉽게 처리할 수 있었던 기능도... React와 Typescript를 사용하다보니 구현에 어려움이 많네요. 아무튼, 아래 그림과 같은 사이트를 선택하면, 여기서 선택한 값으로 라인의 항목이 표시됩니다. 에어리어도 동일합니다.

    o28WJWb.png

     

     

    리엑트 훅(Hook)에서 Select 콘트롤의 value 속성을 채워줘야 합니다. 이 때 현재 Select 콘트롤의 위치(Index)를 알아야 합니다. 그래야 처음 사이트의 항목을 표시할 수 있기 때문입니다. 이렇게 Hook를 연결하면서 상하위의 값을 체크해서 Backend의 RESTful을 호출해야 합니다. 선택 항목에 따라 3개의 Select(ComboBox or DripDownList)가 의존성을 가지면서 갱신하려면 아래와 같이 코드를 작성해야 합니다.

    const selectsReducer = (state, action) => {
      const { type, payload } = action;
      switch (type) {
        case "update_planet": {
          const newCountry = payload.countries.find(
            (c) => c.planet === payload.value
          ).id;
          return {
            planet: payload.value,
            country: newCountry,
            city: payload.cities.find((c) => c.country === newCountry).id,
          };
        }
        case "update_country": {
          return {
            ...state,
            country: payload.value,
            city: payload.cities.find((c) => c.country === payload.value).id,
          };
        }
        case "update_city": {
          return {
            ...state,
            city: payload.value,
          };
        }
        default:
          return { ...state };
      }
    };

     

    위 코드는 백엔드에 데이타를 요청하는 내용이 필요하지만, 이 부분은 각자 처리하면 될거 같습니다. 구조적인 부분을 참고하세요. 각각의 Select에서 이벤트 훅을 사용하는 대신에 한곳에서 각각의 Select를 업데이트하도록 하는게 더 유리하고 관리가 쉽습니다. 하지만~ 리얼타임으로 처리하는 경우엔 이 로직을 사용할 수 없습니다. 예를 들어, 콤보박스를 클릭하는 순간 서버로부터 데이타를 받아와야 한다면 이 방식으로는 처리하기가 쉽지 않습니다. 그래서, useEffect에서 변화를 매번 감지하도록 할수도 있습니다.

    export const SelectList = ({ record, onSave, planets, countries, cities }) => {
      const [selectedPlanet, setSelectedPlanet] = useState(record.planet);
      const [selectedCountry, setSelectedCountry] = useState(record.country);
      const [selectedCity, setSelectedCity] = useState(record.city);
    
      /** handle filteredValues in state */
      const [filteredCountries, setFilteredCountries] = useState([]);
      const [filteredCities, setFilteredCities] = useState([]);
    
      /** use useEffect to update values */
      useEffect(() => {
        const filteredCountries = countries.filter((c) => c.planet === selectedPlanet);
        setFilteredCountries(filteredCountries);
        setSelectedCountry(filteredCountries[0].id);
      }, [selectedPlanet]);
    
      useEffect(() => {
        const filteredCities = cities.filter((c) => c.country === selectedCountry);
        setFilteredCities(filteredCities);
        setSelectedCity(filteredCities[0].id);
      }, [selectedCountry]);
    
      return (
        <div>
          <select value={selectedPlanet}
            onChange={(e) => setSelectedPlanet(e.target.value)}>
            {planets.map((p) => (
              <option key={p.id} value={p.id}>{p.name}</option>
            ))}
          </select>
          <select value={selectedCountry}
            onChange={(e) => setSelectedCountry(e.target.value)}>
            {filteredCountries.map((c) => (
              <option key={c.id} value={c.id}>{c.name}</option>
            ))}
          </select>
          <select
            value={selectedCity}
            onChange={(e) => setSelectedCity(e.target.value)}>
            {filteredCities.map((c) => (
              <option key={c.id} value={c.id}>{c.name}</option>
            ))}
          </select>
          <button onClick={() => onSave({planet: selectedPlanet, country: selectedCountry, city: selectedCity })}>Save</button>
        </div>
      );
    };

     

    가장 간단한 방법은 Select 콘트롤의 갯수가 정해져 있고, 항목들도 고정되어 있는 시나리오일겁니다. 하지만, Select 갯수도 동적이고 그 안의 Option들도 동적인데다 랜덤하다면 어쩔 수 없이 각각의 Select에 Hook을 걸어서 로직적으로 바인딩하고 Select의 Value와 Option 목록을 삭제해야 합니다. 코딩의 자유도가 높지 않은 React, Angular와 같은 환경에서느 어려운 개발이 될겁니다.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.