コード反応ゆったりパンツクローン5



学習内容:


Propsで受け取った値をdepsパラメータに入れることを忘れないでください.
(hookの2番目のパラメータ、例えばuseEffectとuseCallbackをdepsと呼ぶ)
ChatBox/index.tsx
const ChatBox:VFC<Props> =({chat,onSubmitForm,onChangeChat,placeholder}) =>{
    // state 를 관리하는 게 아니라 태그에 직접 접근하고 싶을 때 ref 를 쓴다
    const textareaRef=useRef<HTMLTextAreaElement>(null)
    useEffect(()=>{
        if(textareaRef.current){
            autosize(textareaRef.current);
        }
    },[])
    const onKeydownChat = useCallback((e)=>{
        if(e.key==='Enter'){
            if(!e.shiftKey){
                e.preventDefault();
                onSubmitForm(e);
            }
        }
    },[onSubmitForm])
    // 여기선 deps가 onSubmitForm
WebSocket//Webソケットとは?
サーバとデータのリアルタイム送受信に使用します.
従来のフロントエンド→サーバ、サーバ→フロントエンドの一方向(ポーリングなし)
Webソケットを使用すると双方向に使用できます.
以下のように使用します.
import io from 'socket.io-client';
import React, {useCallback} from 'react';
import axios from 'axios';

const backUrl = 'http://localhost:3095';

const sockets:{[key: string]: SocketIOClient.Socket} = {}; // [key:string] 은 workspace 인데 어떤 데이터가 들어오든 문자열이면 된다 라는뜻
const useSocket = (workspace?:string) => {
    const disconnect = useCallback(() => {
        if (workspace) {
            sockets[workspace].disconnect();
            delete sockets[workspace]; // 연결 끊을 때 
        }
    },[workspace]);

    if(!workspace){
        return [undefined,disconnect];
    }
    sockets[workspace] = io.connect(`${backUrl}/ws-${workspace}`);
    sockets[workspace].emit('hello','world'); // ← 데이터 보내기
    // 서버로 hello 라는 이벤트명으로 world 라는 데이터를 보낸다
    sockets[workspace].on('message',(data)=>{ // ← 데이터 전송하기
        console.log(data);
    })
    // 서버측에서 프론트에서 데이터가 오면 message 라는 이벤트에 콜백함수 적용

    return [sockets[workspace], disconnect]
}

export default useSocket;
スクロールバーを実装するには、react-custom-scrollbarsをインストールします.
コマンドプロンプトで、npm install react-custom-scrollbards--saveを実行します.
タイプスクリプトnpm i-save-dev@types/react-scustom-scrollbarsを実行します.
スクロールバーは次のようになります.
import Chat from '@components/Chat';
import { IDM } from '@typings/db';
import React, { useCallback, useRef, VFC } from 'react';
import Scrollbars from 'react-custom-scrollbars';
import { ChatZone, Section } from './styles';

interface Props{
    chatData?:IDM[];
    // undefined 가 '?' 를 붙여줘서 걸러진다
}

const ChatList:VFC<Props>=({chatData})=>{
    const scrollbarRef = useRef(null);
    const onScroll = useCallback(()=>{

    },[])

    return (
        <ChatZone>
            <Scrollbars autoHide ref={scrollbarRef} onScrollFrame={onScroll}>
            {chatData?.map((chat)=>(
                <Chat key={chat.id} data={chat}/>
            ))}
            </Scrollbars>
        </ChatZone>
    )
}

export default ChatList;
チャットウィンドウの'@hw 02011203'はこのようにラベルに言及しますか?実行中のライブラリ
コマンドプロンプトでnpm i react-remensionsを実行します.
タイプスクリプトを使用すると、npm i--save-dev@types/react-の説明も実行されます.
使用
ChatBox/index.tsx
import {Mention} from 'react-mentions'

...(생략)...

    return(
        <ChatArea>
            <Form onSubmit={onSubmitForm}>
                <MentionsTextarea id="editor-chat" value={chat} onChange={onChangeChat} onKeyDown={onKeydownChat} placeholder={placeholder} ref={textareaRef}>
                    <Mention
                        appendSpaceOnAdd
                        trigger="@"
                        data={memberData?.map((v)=>({id:v.id,display:v.nickname})) || []}
                        renderSuggestion={renderSuggestion}
                    />
                </MentionsTextarea>
...(생략)...
styled componentsに関する内容
関数を呼び出す方法はいろいろあります.
functiona()があれば
a()
a.call();
a.apply();
a.bind();
待って、私はこのような方法であなたを呼ぶことができます.
a``;
呼び方もあります!
この方式をラベル印刷物と呼ぶ.
実際、styledcomponentsを使用して作成されたcssは関数と見なすことができます!
変数に関数を入れることもできます.以下に示します.

export const EachMention = styled.button<{ focus: boolean }>`
  padding: 4px 20px;
  background: transparent;
  border: none;
  display: flex;
  align-items: center;
  color: rgb(28, 29, 28);
  width: 100%;
  & img {
    // & : nested selector
    margin-right: 5px;
  }

  ${({ focus }) =>
    focus &&
    `
    background: #1264a3;
    color: white;
  `};
`;
上のgifのChatBoxのソースコードに適用します.
ChatBox/index.tsx
...(생략)...
    return(
        <ChatArea>
            <Form onSubmit={onSubmitForm}>
                <MentionsTextarea
                    id="editor-chat"
                    value={chat}
                    onChange={onChangeChat}
                    onKeyDown={onKeydownChat}
                    placeholder={placeholder}
                    inputRef={textareaRef}
                    allowSuggestionsAboveCursor
                >
                    <Mention
                        appendSpaceOnAdd
                        trigger="@"
                        data={memberData?.map((v)=>({id:v.id,display:v.nickname})) || []}
                        renderSuggestion={renderSuggestion}
                    />
                </MentionsTextarea>
...(생략)...