コード反応ゆったりパンツクローン3
学習内容:
Inputのある素子を分けて!
(そうでないと、他の部分は再レンダリングされ、最適化が不便になります)
Workspace/index.tsx
<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>
CreateChannelModal/index.tsx 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>
)
コード剥離App.tsx
const App = () => {
return (
<Switch>
<Redirect exact path="/" to="/login"/>
<Route path="/login" component={LogIn}/>
<Route path="/signup" component={SignUp}/>
{/* '/workspace/channel', 'workspace/dm' 이 아니라
아래처럼 주소칸 뒤에 클론을 붙이면 특수한 역할(와일드카드) 역할을 한다.*/}
<Route path="/workspace/:workspace" component={Workspace}/>
{/* 또한 예를 들어 여기에 workspace/channel 주소가 있으면 실행이 안 된다 */}
</Switch>
)
};
Workspace/index.tsx...(생략)...
<Switch>
<Route path="/workspace/:workspace/channel/:channel" component={Channel}/>
<Route path="/workspace/:workspace/dm/:id" component={DirectMessage}/>
</Switch>
...(생략)...
CreateChannelModal/index.tsx// useParams 훅으로 위에 써져있는 파라미터 뒤의 값들을 불러올 수 있다!
import { useParams } from 'react-router';
...(생략)...
const { workspace, channel } = useParams<{workspace:string;channel:string}>();
const onCreateChannel=useCallback(()=>{
axios.post(`/api/workspaces/${workspace}/channels`,{
name:newChannel,
},{
withCredentials:true //쿠키전달
})
},[newChannel]);
これは、上のgifのようにチャンネルを作成するモードに適したコードです.見ればわかる.
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';
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, error,mutate} = useSWR<IUser|false>(
'http://localhost:3095/api/users',
fetcher,
{
dedupingInterval:2000,
}
);
const {data:channelData,mutate:mutateChannel} = useSWR<IChannel[]>(
userData ? `http://localhost:3095/api/workspaces/${workspace}/channels` : null,
fetcher,
)
const onCreateChannel=useCallback((e)=>{
e.preventDefault();
axios.post(`http://localhost:3095/api/workspaces/${workspace}/channels`,{
name:newChannel,
},{
withCredentials:true //쿠키전달
},)
.then(() => {
setShowCreateChannelModal(false);
mutateChannel()
setNewChannel('')
})
.catch((error)=>{
console.dir(error);
toast.error(error.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
Reference
この問題について(コード反応ゆったりパンツクローン3), 我々は、より多くの情報をここで見つけました https://velog.io/@hw020123/리액트-슬랙-클론코딩-3テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol