인프런 커뮤니티 질문&답변

yjym33님의 프로필 이미지
yjym33

작성한 질문수

Slack 클론 코딩[실시간 채팅 with React]

채널 만드는 모달

08:11초 CreateChannelModal 임포트시 오류발생

작성

·

217

0

안녕하세요 제로초님

08:11초에서 CreateChannelModal 

import  할때 아래 setShowCreateChannelModal에서 아래와 같은 오류가 발생합니다. (구글에서 구글링해보고 다 해봤는데 어디가 문제인지 몰라 여쭈어보려고 합니다.)

 

'{ show: boolean; onCloseModal: () => void; setShowCreateChannelModal: Dispatch<SetStateAction<boolean>>; }' 형식은 'IntrinsicAttributes & Props' 형식에 할당할 수 없습니다.
'IntrinsicAttributes & Props' 형식에 'setShowCreateChannelModal' 속성이 없습니다.
ts(2322)

답변 5

0

yjym33님의 프로필 이미지
yjym33
질문자

아 제가 강의를 끝까지 안보고 애기했네요.. 죄송합니다.. 강의도중에 해당 부분을 지우시는거 같아요.. 번거롭게 해드려서 죄송합니다.

0

yjym33님의 프로필 이미지
yjym33
질문자

CreateChannelModal쪽 코드도 올렸습니다. 

이쪽은 오류표시가 따로 뜨지 않았는데.. 뭐가 문제인지 잘 모르겠습니다.

0

yjym33님의 프로필 이미지
yjym33
질문자

import Modal from "@components/Modal";
import useInput from "@hooks/useInput"; // 커스텀 Hooks
import { Button, Input, Label } from "@pages/SignUp/styles";
import React, { VFC, useCallback } from "react";

interface Props {
    show : boolean;
    onCloseModal: () => void;
}

const CreateChannelModal: VFC<Props> = ( {show, onCloseModal }) => {
    const [newChannel, onChangeNewChannel] = useInput('')
    const onCreateChannel = useCallback(() => {}, []);

    return (
      <Modal show={show} onCloseModal={onCloseModal}>
      <form onSubmit={onCreateChannel}>
        <Label id="channel-label">
         <span>채널</span>
         <Input id ="channel" value={newChannel} onChange={onChangeNewChannel} />
        </Label>
        <Button type="submit">생성하기</Button>
      </form>
    </Modal>
    )
}

export default CreateChannelModal;

0

yjym33님의 프로필 이미지
yjym33
질문자

workspace의 index.tsx 전체 코드 첨부하였습니다.

가장 하단의 setShowCreateChannelModal ={setShowCreateChannelModal} 이부분에서 오류가 납니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

CreateChannelModal 코드 보여주세요. 거기에 setShowCreateChannelModal쪽에 타입 미스매치가 있습니다.

0

yjym33님의 프로필 이미지
yjym33
질문자

import {
  Channels,
  Header,
  ProfileImg,
  RightMenu,
  Workspaces,
  WorkspaceWrapper,
  WorkspaceName,
  Chats,
  MenuScroll,
  ProfileModal,
  LogOutButton,
  WorkspaceButton,
  AddButton,
  WorkspaceModal
} from '@layouts/Workspace/styles';
import fetcher from '@utils/fetcher';
import axios from 'axios';
import React,{ VFC, useCallback, useState }  from 'react';
import { Redirect } from 'react-router';
import { Link, Route, Switch } from 'react-router-dom';
import useSWR from 'swr';
import gravatar from 'gravatar';
import loadable from '@loadable/component';
import Menu from '@components/Menu';
import { IUser } from '@typings/db';
import { Button, Input, Label } from '@pages/SignUp/styles';
import useInput from '@hooks/useInput';
import Modal from '@components/Modal';
import { toast } from 'react-toastify';
import CreateChannelModal from '@components/CreateChannelModal';

const Channel = loadable(() => import('@pages/Channel'));
const DirectMessage = loadable(() => import('@pages/Channel'));


const Workspace: VFC = () => {
    const [ showUserMenu, setShowUserMenu] = useState(false);
    const [ ShowCreateWorkspaceModal,setShowCreateWorkspaceModal] = useState(false);
    const [ showWorkspaceModal,setShowWorkspaceModal] = useState(false);
    const [ showCreateChannelModal ,setShowCreateChannelModal] = useState(false);
    const [newWorkspace, onChangeNewWorkspace, setNewWorkspace] = useInput('');
    const [newUrl, onChangeNewUrl, setNewUrl] = useInput('');

    const { data: userData, error, revalidate } = useSWR<IUser | false>('http://localhost:3095/api/users', fetcher);
   
    const onLogout = useCallback(() => {
      axios.post('http://localhost:3095/api/users/logout', null, {
          withCredentials: true,
      })
       .then(() => {
        revalidate();
       })
    }, []);

    const onCloseUserProfile = useCallback((e) => {
      e.stopPropagation();
      setShowUserMenu(false);
    }, []);

    const onClickUserProfile = useCallback(() => { // 토글함수
      console.trace('click');
      setShowUserMenu((prev) => !prev);
    }, []);

    const onClickCreateWorkspace = useCallback(() => {
      setShowCreateWorkspaceModal(true);
    }, []);

    const onCreateWorkspace = useCallback((e) => {
      e.preventDefault();
      if(!newWorkspace || !newWorkspace.trim()) return;
      if(!newUrl || !newUrl.trim()) return;
      if(!newWorkspace) return;
      axios
      .post('http://localhost:3095/api/workspaces', {
        workspace: newWorkspace,
        url: newUrl,
      },   {
        withCredentials: true,
      })
      .then(() => {
        revalidate();
        setShowCreateWorkspaceModal(false);
        setNewWorkspace('');
        setNewUrl('');
      })
      .catch((error) => {
        console.dir(error);
        toast.error(error.response?.data, { position: 'bottom-center'});
      });
    },
      [newWorkspace, newUrl]
    );

    const onCloseModal = useCallback(() => {
      setShowCreateWorkspaceModal(false);
      setShowCreateChannelModal(false);
    }, []);

    if(!userData) {
      return <Redirect to="/login" />
    }

    const toggleWorkspaceModal = useCallback(() => {
      setShowWorkspaceModal((prev) => !prev);
    }, []);

    const onClickAddChannel = useCallback(() => {
      setShowCreateChannelModal(true);
    }, []);

    return(
        <div>
          <Header>
           <RightMenu>
             <span onClick={onClickUserProfile}>
               <ProfileImg src={gravatar.url(userData.nickname, { s: '28px', d: 'retro'})} alt={userData.nickname} />
               {showUserMenu && (
                <Menu style={{ right: 0, top: 38 }} show={showUserMenu} onCloseModal={onCloseUserProfile}>
                  <ProfileModal>
                    <img src= {gravatar.url(userData.nickname, { s: '36px', d: 'retro'})} alt={userData.nickname} />
                    <div>
                      <span id="profile-name">{userData.nickname}</span>
                      <span id="profile-active">Active</span>
                    </div>
                  </ProfileModal>
                  <LogOutButton onClick={onLogout}>로그아웃</LogOutButton>
                </Menu>
               )}
             </span>
            </RightMenu>  
          </Header>
          <WorkspaceWrapper>
            <Workspaces>
              {userData?.Workspaces.map((ws) => {
              return(
                <Link key={ws.id} to={'/workspace/${123}/channel/일반'}>
                  <WorkspaceButton>{ws.name.slice(0, 1).toUpperCase()}</WorkspaceButton>
                </Link>
              )
            })}
             <AddButton onClick={onClickCreateWorkspace}>+</AddButton>
            </Workspaces>
            <Channels>
              <WorkspaceName onClick={toggleWorkspaceModal}>Sleact</WorkspaceName>
              <MenuScroll>
                <Menu show={showWorkspaceModal} onCloseModal={toggleWorkspaceModal} style={{ top: 95, left: 80}}>
                  <WorkspaceModal>
                    <h2>Sleact</h2>
                    <button onClick={onClickAddChannel}>채널 만들기</button>
                    <button onClick={onLogout}>로그아웃</button>
                  </WorkspaceModal>
                </Menu>
              </MenuScroll>
            </Channels>
            <Chats>
              <Switch> {/* workspace 안에서 Switch Route 사용 (중첩 라우팅)  */}
              <Route path="/workspace/channel" component={Channel} />
              <Route path="/workspace/dm" component={DirectMessage} />
              </Switch>
            </Chats>
          </WorkspaceWrapper>
          <Modal show={ShowCreateWorkspaceModal} onCloseModal={onCloseModal}>
            <form onSubmit={onCreateWorkspace}>
              <Label id="Workspace-label">
               <span>워크스페이스 이름</span>
               <Input id ="workspace" value={newWorkspace} onChange={onChangeNewWorkspace} />
              </Label>
              <Label id="Workspace-url-label">
               <span>워크스페이스 url</span>
               <Input id ="workspace" value={newUrl} onChange={onChangeNewUrl} />
              </Label>
              <Button type="submit">생성하기</Button>
            </form>
          </Modal>
          <CreateChannelModal
            show={showCreateChannelModal}
            onCloseModal={onCloseModal}
            setShowCreateChannelModal={setShowCreateChannelModal}
            />
        </div>
    );
};

export default Workspace;
yjym33님의 프로필 이미지
yjym33

작성한 질문수

질문하기