채널 생성시 channelData.map is not a function
579
작성한 질문수 6
채널생성 클릭하면 channeldata.map is not a function이라고 에러가 뜨는데
channelData뿌려지는곳에 ?옵셔널도 줬고..
아래처럼 잘 작성한것같은데 어딜 놓쳤는지 모르겠습니다.
새로고침하면 추가된 채널명이 출력됩니다.
workspace
import fetcher from '@utils/fetcher';
import axios from 'axios';
import React, { FC, useCallback, useState } from 'react';
import { Navigate, useParams } from 'react-router-dom';
import useSWR from 'swr';
import {
AddButton,
Channels,
Chats,
Header,
LogOutButton,
MenuScroll,
ProfileImg,
ProfileModal,
RightMenu,
WorkspaceButton,
WorkspaceModal,
WorkspaceName,
Workspaces,
WorkspaceWrapper,
} from './styles';
import gravatar from 'gravatar';
import Menu from '@components/menu';
import { Link } from 'react-router-dom';
import { IChannel, IUser, IWorkspace } 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 Workspace: FC = ({ children }) => {
const { workspace, channel } = useParams<{ workspace: string; channel: string }>();
const { data: userData, error, mutate } = useSWR<IUser | false>('/api/users', fetcher, { dedupingInterval: 2000 });
const { data: channelData } = useSWR<IChannel[]>(userData ? `/api/workspaces/${workspace}/channels` : null, fetcher);
if (!userData) {
return <Navigate to="/login" />;
}
const [showUserMenu, setShowUserMenu] = useState(false);
const [newWorkspace, onChangeNewWorkspace, setNewWorkspace] = useInput('');
const [newUrl, onChangeNewUrl, setNewUrl] = useInput('');
const [showWorkspaceModal, setShowWorkspaceModal] = useState(false);
const [showCreateChannelModal, setShowCreateChannelModal] = useState(false);
const [showCreateWorkspaceModal, setShowCreateWorkspaceModal] = useState(false);
//functions
const onLogout = useCallback(() => {
axios
.post('/api/users/logout', null, {
withCredentials: true,
})
.then((res) => {
mutate(res.data);
});
}, []);
const onClickUserProfile = useCallback(() => {
setShowUserMenu(!showUserMenu);
}, [showUserMenu]);
const onClickCreateWorkspace = useCallback(() => {
setShowCreateWorkspaceModal(true);
}, []);
const onCreateWorkspace = useCallback(
(e) => {
e.preventDefault();
if (!newWorkspace || !newWorkspace.trim()) return;
if (!newUrl || !newUrl.trim()) return;
//trim ->띄어쓰기 하나도 통과 돼버리는걸 막는다.
axios
.post(
'/api/workspaces',
{
workspace: newWorkspace,
url: newUrl,
},
{
withCredentials: true,
},
)
.then((res) => {
mutate(res.data);
setShowCreateWorkspaceModal(false);
setNewWorkspace(''), setNewUrl('');
})
.catch((err) => {
console.dir(err);
toast.error(error.response?.data, { position: 'bottom-center' });
});
},
[newWorkspace, newUrl],
);
const onCloseModal = useCallback(() => {
setShowCreateWorkspaceModal(false);
setShowCreateChannelModal(false);
}, []);
const toggleWorkspaceModal = useCallback(() => {
setShowWorkspaceModal(!showWorkspaceModal);
}, [showWorkspaceModal]);
const onClickAddChannel = useCallback(() => {
setShowCreateChannelModal(true);
}, []);
return (
<div>
<Header>
<RightMenu>
<span onClick={onClickUserProfile}>
<ProfileImg src={gravatar.url(userData.email, { s: '28px', d: 'retro' })} alt={userData.nickname} />
{showUserMenu && (
<Menu style={{ right: 0, top: 38 }} onCloseModal={onClickUserProfile} show={showUserMenu}>
<ProfileModal>
<img src={gravatar.url(userData.email, { s: '28px', 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: IWorkspace) => {
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={onClickInviteWorkspace}>워크스페이스에 사용자 초대</button> */}
<button onClick={onClickAddChannel}>채널 만들기</button>
<button onClick={onLogout}>로그아웃</button>
</WorkspaceModal>
</Menu>
{channelData?.map((v, idx) => (
<div key={idx}>{v.name}</div>
))}
</MenuScroll>
</Channels>
<Chats> {children}</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;
createChannelModal
import Modal from '@components/modal';
import useInput from '@hooks/useInput';
import { Button, Input, Label } from '@pages/signup/styles';
import { IChannel, IUser } from '@typings/db';
import fetcher from '@utils/fetcher';
import axios from 'axios';
import React, { useCallback, VFC } from 'react';
import { useParams } from 'react-router-dom';
import { toast } from 'react-toastify';
import useSWR from 'swr';
interface Props {
show: boolean;
onCloseModal: () => void;
setShowCreateChannelModal: (flag: boolean) => void;
}
const CreateChannelModal: VFC<Props> = ({ show, onCloseModal, setShowCreateChannelModal }) => {
const [newChannel, onChangeNewChannel, setNewChannel] = useInput('');
const { workspace, channel } = useParams<{ workspace: string; channel: string }>();
const { data: userData } = useSWR<IUser | false>(`/api/users`, fetcher);
const { data: channelData, mutate } = useSWR<IChannel[]>(
userData ? `/api/workspaces/${workspace}/channels` : null,
fetcher,
);
const onCreateChannel = useCallback(
(e) => {
e.preventDefault();
axios
.post(
`/api/workspaces/${workspace}/channels`,
{
name: newChannel,
},
{ withCredentials: true },
)
.then((res) => {
setShowCreateChannelModal(false);
mutate(res.data);
setNewChannel('');
})
.catch((err) => {
console.dir(err);
toast.error(err.response?.data, { position: 'bottom-center' });
});
},
[newChannel],
);
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;
답변 3
0
혹시 어떻게 해결하셨나용...? 저도 똑같이 뜨네요..
0
우선 then 안에서 res.data 잘 들어오는거 확인했고,
mutate(res.data,false)로
swr이 전역관리하는거로 이해했는데
const onCreateChannel = useCallback(
(e) => {
e.preventDefault();
axios
.post(
`/api/workspaces/${workspace}/channels`,
{
name: newChannel,
},
{ withCredentials: true },
)
.then((res) => {
setShowCreateChannelModal(false);
mutate(res.data, false);
console.log(res.data, 'res.data');
setNewChannel('');
})
.catch((err) => {
console.dir(err);
toast.error(err.response?.data, { position: 'bottom-center' });
});
},
[newChannel],
);
이렇게 찍어보면
배열이 풀리면서? 에러나는 것 같습니다..
이런식으로 처리해줘야 하나 해봤는데 아닌것같고...
고민 계속 해보겠습니다..
기본 셋팅과 관련하여
0
91
1
초기 셋팅 back과 front만 남겨두고 다 지운 후 진행 방법
0
96
2
focus 시에만 화면 업데이트 되는 이유 + 해결방법
0
149
2
useEffect 개수 관리
0
109
2
라이브러리 서치 방법
0
104
2
함수 정의 패턴
0
77
1
npm run dev 에러
0
152
3
npx webpack 후 에러
0
178
2
'void' 형식 식의 truthiness를 테스트할 수 없습니다.ts(1345)
0
143
2
사용자 가입시 에러발생 (TypeError: Cannot read properties of null (reading 'addMembers')
1
178
2
초기세팅중 packge.json 에러떠요
0
155
2
CORS - Access-Control-Allow-Origin 누락 문제
0
431
3
로그인 페이지 무한 새로고침 현상
0
598
2
Module not found: Error: Can't resolve './App' 에러
0
956
1
배포 방법
0
296
2
npm run dev 시 빌드가 매우 느려졌습니다
0
989
2
alias 경로 설정 오류
0
449
2
fetcher 함수의 data 값이 두번 찍히는 이유
0
275
1
제네릭 질문
0
217
2
ts-node 대신 tsx 사용여부
0
373
1
배포 관련 질문
0
247
1
[nginx + https] 서비스를 실행하면 niginx가 아닌 서비스 화면을 보여주게 하고 싶습니다.
0
385
2
[배포하기] webpack에 aws 퍼블릭 IPv4 주소 와 포트 주소를 작성하고 나서 빌드후 실행하면 오류가 발생합니다.
0
336
1
users 호출 시 쿠키가 담기지 않는 이슈 질문드립니다.
0
247
2





