TIL 34일차 : 기능구현 (유저 검색 input 처리 및 css 수정 )

KHW·2021년 11월 1일
0

TIL

목록 보기
38/39

목표

  1. online / offline을 유저목록에서 쓸 방법 생각
  2. coverImage로 받아온 image 크기가 다 다르므로 고정하기
  3. 검색해서 하나만 찾는 기능 구현
  4. 배경색 똑같이 맞추기
  5. container (styled 컴포넌트) 이름 수정하기
  6. 팀원분꺼 merge하기
  7. 온라인 / 오프라인 값 온라인 먼저 정렬 후 보여주기
  8. loading 기능 잘 되게 해보기
  9. 로그아웃 세션 스토리지 다시 체크

1. online / offline을 유저목록에서 쓸 방법 생각

API를 통해 받아온 online / offline 기능을 UI적으로 차이를 이용하기 위해
Ant-design의 Switch 컴포넌트를 사용했다.

{getAllUserState.map(
            ({ isOnline, fullName, email, image, coverImage }) => {
              return (
                <div>
                  <Switch
                    checked={isOnline}
                    checkedChildren="online"
                    unCheckedChildren="offline"
                  />
  .....
  
  

API를 통해 받아온 값을 모아 둔 State인
getAllUserState 부분의 isOnline의 true false 여부에 따라
checkChildren이 되는지 unCheckedChildren이 되는지 확인 할 수 있다.

이와 같이 online일 때와 offline일 때를 눈으로 확인 할 수 있다.

2. coverImage로 받아온 image 크기가 다 다르므로 고정하기

	<Card
                    style={{ width: 300, marginTop: 16 }}
                    loading={loading}
                    cover={
                      <img
                        alt="example"
                        src={
                          coverImage
                            ? coverImage
                            : 'https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png'
                        }
                        height="250px"
                      />
                    }
                  >

height를 250px로 img의 세로를 고정해주어
img가 그 이상의 크기가 들어와도 250으로 고정시켜 처리해준다.

3. 검색해서 하나만 찾는 기능 구현

현재 상황은 모든 정보를 담은 배열이 State로 존재하고
input을 통해 해당 버튼을 순회하면서 검색 값에 맞는 fullName 대상만
값이 나오게 만드는 목표다.
이를 위해서는 렌더링 되는 값(배열)이 우선 필요하고 검색으로 찾은 값(객체)이 필요하고

const GetUsers = async () => {
  return await axios({
    method: 'get',
    url: `${API_END_POINT}/users/get-users`,
  })
    .then((response) => response.data)
    .then((data) => {
      return data
    })
    .catch((error) => {
      console.log(error)
    })
}

const GetOnlineUsers = async () => {
  return await axios({
    method: 'get',
    url: `${API_END_POINT}/users/online-users`,
  })
    .then((response) => response.data)
    .then((data) => {
      return data
    })
    .catch((error) => {
      console.log(error)
    })
}

const Admin = () => {
  const [isAllUsersShow, setIsAllUsersShow] = useState(true)
  const [isOnlineUsersShow, setIsOnlineUsersShow] = useState(false)
  const [getAllUserState, setGetAllUserState] = useState([])
  const [getCopyAllUserState, setGetCopyAllUserState] = useState([])
  const [getOnlineUserState, setGetOnlineUserState] = useState([])
  const [loading, setLoading] = useState(true)

  const onChange = (checked) => {
    setLoading(!checked)
  }

  useEffect(() => {
    const fetchUsers = async () => {
      const allData = await GetUsers()
      setGetCopyAllUserState(allData)
      setGetAllUserState(allData)
      onChange(true)
      const onlineData = await GetOnlineUsers()
      setGetOnlineUserState(onlineData)
    }
    fetchUsers()
  }, [])

  GetUsers()

  const headerName = {
    titleName: ['유저 목록', '접속중인 유저 목록'],
    keyName: ['allUsers', 'onlineUsers'],
  }

  const clickHeaderHandler = ({ key }) => {
    if (headerName.keyName[key] === 'allUsers') {
      setIsAllUsersShow(true)
      setIsOnlineUsersShow(false)
    } else if (headerName.keyName[key] === 'onlineUsers') {
      setIsAllUsersShow(false)
      setIsOnlineUsersShow(true)
    }
  }

  const changeUserHanlder = ({ target }) => {
    if (target.value === '') {
      setGetAllUserState(getCopyAllUserState)
    }
  }

  const searchUserHandler = (e) => {
    let target
    const isTargetExist = getAllUserState.some(
      ({ isOnline, fullName, email, image, coverImage }) => {
        target = [{ isOnline, fullName, email, image, coverImage }]
        return e === fullName
      },
    )
    if (isTargetExist) {
      setGetAllUserState(target)
    } else {
      message.warning('존재하지 않는 유저의 이름을 입력했습니다')
    }
    console.log(isTargetExist, target)
  }

  return (
    <>
      <Menu theme="dark" mode="horizontal" defaultSelectedKeys={['0']}>
        {new Array(2).fill(null).map((_, index) => {
          const key = index
          return (
            <Menu.Item
              key={key}
              onClick={clickHeaderHandler}
            >{`${headerName.titleName[key]}`}</Menu.Item>
          )
        })}
      </Menu>

      <AllUsersContainer display={isAllUsersShow} className="allUsersContainer">
        <Search
          className="searchContainer"
          placeholder="fullName 검색"
          enterButton="Search"
          size="large"
          onChange={changeUserHanlder}
          onSearch={searchUserHandler}
        />
        <CardGrid>
          {getAllUserState.map(
            ({ isOnline, fullName, email, image, coverImage }) => {
              return (
                <div>
                  <Switch
                    checked={isOnline}
                    checkedChildren="online"
                    unCheckedChildren="offline"
                  />
                  <Card
                    style={{ width: 300, marginTop: 16 }}
                    loading={loading}
                    cover={
                      <img
                        alt="example"
                        src={
                          coverImage
                            ? coverImage
                            : 'https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png'
                        }
                        height="250px"
                      />
                    }
                  >
                    <Meta
                      avatar={
                        <Avatar
                          src={
                            image ? image : 'https://joeschmoe.io/api/v1/random'
                          }
                        />
                      }
                      title={fullName}
                      description={email}
                    />
                  </Card>
                </div>
              )
            },
          )}
        </CardGrid>
      </AllUsersContainer>
      <OnlineUsersContainer
        display={isOnlineUsersShow}
        className="onlineUsersContainer"
      >
        <CardGrid>
          {getOnlineUserState.length !== 0
            ? getOnlineUserState.map(
                ({ isOnline, fullName, email, image, coverImage }) => {
                  return (
                    <>
                      <Card
                        style={{ width: 300, marginTop: 16 }}
                        loading={loading}
                        cover={
                          <img
                            alt="example"
                            src={
                              coverImage
                                ? coverImage
                                : 'https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png'
                            }
                          />
                        }
                      >
                        <Meta
                          avatar={
                            <Avatar
                              src={
                                image
                                  ? image
                                  : 'https://joeschmoe.io/api/v1/random'
                              }
                            />
                          }
                          title={fullName}
                          description={email}
                        />
                      </Card>
                    </>
                  )
                },
              )
            : ''}
        </CardGrid>
      </OnlineUsersContainer>
    </>
  )
}

export default Admin

input 태그 상황정리

    1. input에 fullName을 입력하고 성공했을때
      1) searchUserHandler 실행
      2) getAllUserState.some으로 순회
      (forEach를 사용하지않은 이유는 하다가 멈출 가능성이 많기때문)
      3) isTargetExist은 input 검색에 맞는 fullName이 존재하면 true 없으면 false를 처리
      4) true이면 setGetAllUserState(target)를 실행해서 getOnlineUserState 부분의 값이 바뀌어 렌더링이 된다.
      5) 해당 target만 렌더링 처리되어 나타난다.
    1. input에 fullName 입력하고 실패했을때
      1) searchUserHandler 실행
      2) getAllUserState.some으로 순회
      (forEach를 사용하지않은 이유는 하다가 멈출 가능성이 많기때문)
      3) isTargetExist은 input 검색에 맞는 fullName이 존재하면 true 없으면 false를 처리
      4) false이면 message.warning('존재하지 않는 유저의 이름을 입력했습니다') 메세지를 출력한다.
    1. input 태그를 뒤로 옮겨서 빈 태그가 될때
      1) changeUserHanlder가 실행
      2) target.value === '' 체크
      3) setGetAllUserState(getCopyAllUserState)를 통해 이전에 Copy한 모든 유저의 정보를 가진 state를 실행해서 getOnlineUserState 부분의 값이 바뀌어 렌더링이 된다.
      4) 처음 검색을 전부 했을때와 같은 결과가 나타난다.

4. 배경색 똑같이 맞추기

.onlineUsersContainer {
  max-width: auto;
  max-height: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: linear-gradient(#3f87a6, #ebf8e1, #f69d3c);
}

.allUsersContainer {
  max-width: auto;
  max-height: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: linear-gradient(#3f87a6, #ebf8e1, #f69d3c);
}

각각의 class에 linear-gradient 부여

5. container (styled 컴포넌트) 이름 수정하기

styled 컴포넌트는 대문자로 시작을 해야하는 것 같다 (소문자면 계속 에러가 났다. )

6. develop 브랜치 merge

  • 방법
  1. 로컬의 origin/develop 브랜치로 옮김
  2. pull하기
  3. 내가 만든 branch로 옮김 (origin/dev/khw970421)
  4. 현재 내가만든 branch에 (origin/dev/khw970421)
    merge로 orgin/develop 부분은 분기병합한다.
  5. 이때 동기화가 뜨는데 이를 클릭하면 원격 github 서버의 나의
    dev/khw970421까지 같이 merge 처리가 된다.
    (origin/dev/khw970421로 branch를 써서 그런지 이런 동기화가 편한듯 하다)

7. 온라인 / 오프라인 값 온라인 먼저 정렬 후 보여주기

기존 상황

모든 User들을 보여주는 곳에서 online과 offline 전부 정렬 없이 받아온 API를 통해 순서대로 결과를 보여준다.

  • 이를 , 온라인 유저만 위에 보여주고 오프라인 유저는 아래로 정렬하면 어떨까 하는 팀원의 의견에 따라 시도를 해보았다.

기존 코드

 useEffect(() => {
    const fetchUsers = async () => {
      const allData = await GetUsers()
      setGetCopyAllUserState(allData)
      setGetAllUserState(allData)
      onChange(true)
      const onlineData = await GetOnlineUsers()
      setGetOnlineUserState(onlineData)
    }
    fetchUsers()
  }, [])

받아온 allData의 부분을 통해 setState 기능을 통해 렌더링을 진행시킨다.

수정한 코드


  const onlineFirstCheck = { false: 0, true: 1 }

  useEffect(() => {
    const fetchUsers = async () => {
      const allData = await GetUsers()
      const sortAllData = allData.sort(
        (a, b) => onlineFirstCheck[b.isOnline] - onlineFirstCheck[a.isOnline],
      )
      setGetCopyAllUserState(sortAllData)
      setGetAllUserState(sortAllData)
      onChange(true)
      const onlineData = await GetOnlineUsers()
      setGetOnlineUserState(onlineData)
    }
    fetchUsers()
  }, [])

onlineFirstCheck에 의해 false는 0을 가르키고 true는 1을 가르킨다.
sort 메소드를 통해 각각의 a.isOnline과 b.isOnline은 falsetrue를 지칭하고
이는 onlineFirstCheck[false]는 0을 onlineFirstCheck[true]는 1을 가르킨다.
이를 통해 정렬을 시키면 오름차순으로 값이 큰 true인 대상들
즉, isOnline이 true인 온라인 상태인 대상들이 앞에 오게된다.

수정결과

이와같이 위쪽부터 online 부분을 먼저 처리하고
나중에 offline 부분을 처리한다.

해당 관련 자료는 이곳을 참고하여 했다.

9. 로그아웃 세션 스토리지 다시 체크

나의 실수로 removeItem 부분을 setItem 기능을 구현했다.

export const removeItem = (target) => {
  //sessionStorage.setItem(target) 	//오류원인
  sessionStorage.removeItem(target)	//수정결과
}
profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자

0개의 댓글