섹션 2: React, React Router, CSS를 사용하여 멋진 드롭다운 메뉴를 구축합니다.

내가 마지막으로 구축~쿨~드롭다운 메뉴에 대한 토론을 한 후에 나는 두 번째 부분을 쓰는 건의를 받았다.
"일반적으로 구성 요소를 제작할 때 재사용이 가능하고 간단하기 때문에 재접근이 거의 필요 없다"고 지적했다.
나는 이 일을 마음에 두고 있다.아래에서, 나는 밑에 있는 메뉴를 다시 사용할 수 있고 간단하게 재구성하려고 시도했다.

jump to the code on GitHub


지도의


목표는 앞의 드롭다운 메뉴를 사용하고 코드를 다시 쓰는 것입니다. 그러면 JSON 객체의 데이터를 교환하여 원본 객체와 같은 구조와 스타일을 가진 드롭다운 메뉴를 만들 수 있습니다.

카탈로그

  • 초보 쓰레기
  • 매핑 JSON 객체
  • 동적 스타일
  • 동적 노선
  • 결론
  • 초보 쓰레기


    우선, duplicated the original repository은 위조 데이터를 포함하는 JSON 파일을 만들었습니다.

    JSON 객체 매핑


    구성 요소를 동적화하기 위해서 나는 map()을 사용한다.맵은 무한 크기의 그룹을 JSX로 변환할 수 있기 때문에 React 응용 프로그램에서 흔히 볼 수 있습니다.이것은 구성 요소를 추상화하여 유연성과 중용성을 가지게 했다.
    원래 Menu 어셈블리는 다음과 같이 반환됩니다.
        return (
            <div className="Menu">
                <div className={"m-item m-logo"}
                    onClick={() => setOpenMenu(!openMenu)}>
                    Menu
                </div>
                <div className={setClassNames(1)}
                    onClick={() => pushToRoute("/dashboard")}>
                    Dashboard
                </div>
                <div className={setClassNames(2)}
                    onClick={() => pushToRoute("/settings")}>
                    Settings
                </div>
                <div className={setClassNames(3)}
                    onClick={() => pushToRoute("/")}>
                    Sign out
                </div>
            </div>
      );
    
    모든 항목에 자신의div와 속성이 있음을 보실 수 있습니다.재구성 버전에서 쿠키커터 메뉴 항목을 정의했고 JSON의 모든 메뉴 항목을 map()으로 정의했습니다.
    새로운 보상은 다음과 같습니다.
        return (
            <div className="Menu">
                <div className={"m-item m-logo"}
                    onClick={() => setOpenMenu(!openMenu)}>
                    Menu
                </div>
    
                {renderMenuItems(data)}
    
            </div>
      );
    
    첫 번째 메뉴 항목은 자신의 div에 저장됩니다. 이 항목의 역할은 밑에 있는 메뉴를 여는 단추와 유사합니다.메뉴가 닫히고 다른 메뉴 항목이 뒤에 숨겨지면 표시됩니다.
    이 아래에서 renderMenuItems() 함수를 호출합니다. 이 함수는 JSON 대상을 매개 변수로 합니다.renderMenuItems()은 복잡하다.나는 모든 기능을 보여준 후에 하나하나 설명할 것이다.
        // render each menu item after Menu button clicked
        const renderMenuItems = data => {    
            const colorArr = ["#9b5de5", "#f15bb5", "#00BBF9"];
    
            let colorCounter = -1;
            return data.menu.map((item, index) => {
    
                // if counter is over 2, resets to 0
                // for colorArr bracket notation to get sequence of colors
                colorCounter < 2 ? colorCounter++ : colorCounter = 0
    
                // dynamic styles for each menu item 
                const itemStyle = {
                    "top": `${index * 1.8}em`,
                    "backgroundColor": colorArr[colorCounter]
                }
    
                return (
                    <div className="m-item"
                        key={item.id}
                        style={openMenu ? itemStyle : null}
                        onClick={() => pushToRoute(item.route)}>
                        {item.name}
                    </div>
                )
            })
        }
    
    다음 절에서 동적 스타일에 대한 내용에서 나는 colorArr, colorCounteritemStyle을 설명할 것이다.
    우선, 이 줄을 주의해라.
            return data.menu.map((item, index) => {
    
    map()data, 즉 JSON 객체 매개변수로 돌아갑니다.map() 대수 그룹의 모든 항목이 리셋을 실행하고 새 수조에서 이 함수의 결과를 되돌려줍니다.map()은 두 개의 매개 변수를 사용할 수 있다.첫 번째 매개 변수는 그룹의 항목입니다.나는 item으로 표시했다.두 번째는 항목별 인덱스로 index으로 표시됩니다.
    현재 이 부분:
                return (
                    <div className="m-item"
                        key={item.id}
                        style={openMenu ? itemStyle : null}
                        onClick={() => pushToRoute(item.route)}>
                        {item.name}
                    </div>
                )
    
    map()의 각 항목에 대해 동적 JSX를 반환합니다.이것들은 우리 메뉴 항목의div가 될 것입니다.각 항목에는 id, nameroute이 있습니다.
    나는 모든 div에 m-item 클래스를 부여했는데 원래의 클래스와 같다.그들은 onClick을 촉발한 pushToRoute() 사건을 얻었다.매개변수가 JSON 객체에서 route인 경우를 제외하고 원래 매개변수와 동일합니다.각각 JSON의 id의 키를 획득합니다.마지막으로 JSON 객체의 name을 div의 텍스트로 표시합니다.
    참고로 JSON 메뉴 항목은 다음과 같습니다.
          {
            "id": "001",
            "name": "Dashboard",
            "route": "/dashboard"
          }
    

    동적 스타일


    CSS는 드롭다운 애니메이션과 스타일을 담당합니다.원래 메뉴에서, 나는 프로젝트에 클래스를 추가하기 위해 setClassNames()이라는 함수를 사용했다.그리고 나는 모든 항목의 색깔과 길이를 포함하여 하나의 단독 클래스를 만들었다.
    클래스 이름을 추가하여 변환을 트리거하려면 다음과 같이 하십시오.
        // parameter num corresponds to .open-# classes
        // is assigned when Menu clicked triggering animated dropdown
        const setClassNames = num => {
            const classArr = ["m-item"];
            if (openMenu) classArr.push(`open-${num}`)
            return classArr.join(' ')
        }
    
    추가된 클래스 이름:
    .open-1{
        top: 1.8em;
        background-color: #9b5de5;
    }
    .open-2{
        top: 3.6em;
        background-color: #f15bb5;
    }
    .open-3{
        top: 5.4em;
        background-color: #00BBF9;
    }
    
    비록 이렇게 하면 가능하지만 중용하기는 쉽지 않다.나는 모든 추가 항목을 수동으로 맞춤법으로 새 open-#을 작성해야 할 뿐만 아니라, 많은 추가 코드 줄을 사용해야 한다.
    나는 새 메뉴 항목에 map()을 사용했기 때문에, 걸으면서 스타일을 계산할 수 있다.CSS의 두 부분이 필요합니다.
  • top은 목록에 있는 숫자 항목의 크기(1.8, 3.6, 5.4, 7.2 등)를 곱한 1.8em으로 설정됩니다.
  • background-color의 세 가지 색상 육각 중 하나로 설정됩니다(#9b5de5, #f15bb5, #00BBF9).
  • Render Menu Items 다시 보기.
        // render each menu item after initial Menu button
        const renderMenuItems = data => {    
            const colorArr = ["#9b5de5", "#f15bb5", "#00BBF9"];
    
            let colorCounter = -1;
            return data.menu.map((item, index) => {
    
                // if counter is over 2, resets to 0
                // for colorArr bracket notation to get sequence of colors
                colorCounter < 2 ? colorCounter++ : colorCounter = 0
    
                // dynamic styles for each menu item 
                const itemStyle = {
                    "top": `${index * 1.8}em`,
                    "backgroundColor": colorArr[colorCounter]
                }
    
                return (
                    <div className="m-item"
                        key={item.id}
                        style={openMenu ? itemStyle : null}
                        onClick={() => pushToRoute(item.route)}>
                        {item.name}
                    </div>
                )
            })
        }
    
    React를 사용하면 스타일을 요소에 객체로 추가할 수 있으며 속성은 JavaScript의camelcase 구문으로 작성됩니다.itemStyle에서 top의 크기를 설정했습니다.map()이 JSON을 교체할 때, 나는 map() 인덱스 파라미터를 사용하여 동적으로em 크기를 증가시켰다.background-color은 좀 까다롭다.나는 3개의 색 16진수를 포함하는 colorArr이라는 수조를 설정했다.이것들을 방문하기 위해서, 나는hexes에 접근하기 위해 colorCounter이라는 계수기를 설치했다.colorCounter은 처음에 -1로 설정되었습니다.나는 0, 1, 2를 연속적으로 교체하기 위해 map()이 끝날 때까지 이 삼원 코드를 인코딩했다.
                // if counter is over 2, resets to 0
                // for colorArr bracket notation to get sequence of colors
                colorCounter < 2 ? colorCounter++ : colorCounter = 0
    
    만약 계수기가 2보다 작다면, 나는 1을 더할 것이다.만약 2를 초과한다면, 나는 계수기를 0으로 초기화할 것이다.따라서 맵()이 실행되면 계수기는 0, 1, 2, 0, 1, 2...의 시간을 실행합니다.

    Check out Andrew Bone's for a more succinct way of getting the colorCounter number sequence.

    itemStyle에서 “backgroundColor”을 color Arr[color Counter]로 설정합니다.따라서 색상은 순서대로 나타납니다.
    마지막으로 첫 번째 메뉴 항목을 눌렀을 때만 topbackground-color 속성을 프로젝트에 추가해야 합니다.
    앞에서 말한 바와 같이, 눌렀을 때, 맨 위 메뉴 항목은true와false 사이를 openMenu, 즉 useState 연결로 전환합니다.
    나는 모든 div에게 스타일 속성을 하나 주었다.
        style={openMenu ? itemStyle : null}
    
    만약 top이true라면, 나는 여기서 3원을 사용하여 새로운 background-coloropenMenu을 포함하는 대상을 되돌려줍니다.false인 경우 null을 수신합니다.

    동적 라우팅


    마지막 부분은 SwitchApp.js 문장을 되돌려주고 동적 렌더링 루트입니다.
    각 메뉴 항목에 해당하는 map()을 설정하기 위해 route과 같은 JSON 객체를 사용할 수 있습니다.
    const App = () => {
      return (
        <BrowserRouter>
          <div className="App">
            {/* dropdown menu */}
            <Menu/>
            {/* routes */}
            <Switch>
              {/* map same data as dropdown to 
                create route for each item */}
              {data.menu.map(item =>{
                return(
                  <Route key={item.id}
                    exact path={item.route} 
                    component={null} />
                )
              })}
            </Switch>
          </div>
        </BrowserRouter>
      );
    }
    
    
    다시 한 번, 나는 이 메뉴가 응용 프로그램의 실제 구성 요소를 빠뜨렸다.사용할 수 있는 경우 구성 요소 이름을 포함하도록 JSON을 수정하거나 JSON의 ID에 대응하는 검색 테이블을 설정할 수 있습니다.

    결론


    내 코드를 다시 방문하고 최초의 생각을 개선하는 것은 정말 대단하다.다시 한 번 Andrew Bone이 도전해 주셔서 감사합니다.나는 내가 두 번째로 더욱 유연하고 중용할 수 있는 도구를 창조했다고 생각한다.
    피드백이나 제안이 있으면 문의하십시오.댓글이나 메일로 [email protected]을 보내주세요.어쨌든 읽어 주셔서 감사합니다.최고야, 제이슨.

    좋은 웹페이지 즐겨찾기