묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨처음 만난 리액트(React)
(실습) 섭씨온도와 화씨온도 표시하기 관련
왜 화씨, 섭씨가 바뀌면 서로 서로 영향을 주면서 같이 바뀌는지 그 흐름이 정확히 이해가 안되네요.. console.log로 도배해서 파악한 바로는 아래와 같습니다.[섭씨를 바꾼다는 가정]TemperatureInput 컴포넌트의 value가 바뀜TemperatureInput 컴포넌트의 props.onTemperatureChange(event.target.value); 호출Calculator 컴포넌트의 handleCelsiusChange 호출setTemperature(temprature)와 setScale('c') 호출하여 temprature, scale의 state가 바뀜state가 바뀌었으니 Calculator 컴포넌트가 재생성(?)Calculator 컴포넌트의 return에 TemperatureInput temperature props에 celsius, fahrenheit가 업데이트 된채로 TemperatureInput 컴포넌트 재생성(?)TemperatureInput 컴포넌트의 input은 props.temperature를 value로 보여주고 있으니 각각 바뀜위 가정의 흐름이 대충 맞는건지 궁금합니다! 뭔가 어거지로 끼워맞춘건지 제대로 파악하고 있는지 애매하네요...
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
섹션5 데이터 추가하기 강의에 질문있습니다.
섹션 5 useRef , 데이터 추가하기강의에서 useRef가 dom을 지정하기 위해 사용한다고 이해했거든요?근데 데이터를 전달을 위해const dataID = useRdf(0)하고dataId.current += 1처럼변수같이 사용하는데그냥 변수처럼도 사용한거는건가요? 아니면 저가 이해를 못한 사용 의미가 있는건가요제 생각엔 그냥 변수 하나 0으로 초기화하고 그걸 써도 되지 않나란 생각이 들어서요
-
미해결Slack 클론 코딩[실시간 채팅 with React]
SWR DevTools 관련
안녕하세요 SWR관련 질문이 있습니다.혹시 React 18버전에서는 SWR DevTools를 어떻게 사용할 수 있는지 부탁 드립니다.감사합니다.
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
db쪽에 자꾸 에러가 납니다
현재 MySQL을 사용해서 선생님 강의를 보며 모델을작성중인데 계속 이런 에러가 뜹니다. django.db.utils.OperationalError: (1054, "Unknown column 'accounts_user.password' in 'field list'")accounts/models.pyfrom django.conf import settings from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): pass./ serializers.pyfrom rest_framework import serializers from django.contrib.auth import get_user_model User = get_user_model() class SignupSerializer(serializers.ModelSerializer): #pw 보안 password = serializers.CharField(write_only=True) def create(self, validated_data): user = User.objects.create(username=validated_data["username"]) user.set_password(validated_data["password"]) #암호화된 비번 저장 user.save() return user class Meta: model = User fields = ["pk", "username", "password"]./views.pyfrom django.contrib.auth import get_user_model from django.shortcuts import render from rest_framework.permissions import AllowAny from rest_framework.generics import CreateAPIView from .serializers import SignupSerializer #회원가입 뷰 #createapiview 이므로 get 메소드 허용X class SignupView(CreateAPIView): model = get_user_model() serializer_class = SignupSerializer permission_classes = [ AllowAny,#실제로 회원가입할 때는 로그인은 되면 안됨 ] 그리고 accounts의 user를 참조하면서 라벨과 이미지를 첨부할 수있는 mainfunc의./models.pyfrom django.db import models from django.conf import settings from django.contrib.auth.models import User class TImestampedModel(models.Model): # 기본 필드값 created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: abstract = True class Post(TImestampedModel): author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) label = models.CharField(max_length=50, default='') images = models.ImageField(upload_to='images/%Y/%m/%d', blank=True) def __str__(self): return f'{self.author}' ./views.py from rest_framework.viewsets import ModelViewSet from .serializers import PostSerializer from .models import Post from rest_framework.permissions import AllowAny from django.db.models import Q # CRUD가 모두 들어간 API를 지원 class PostViewSet(ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer #permission_classes = [AllowAny] #FIXME: 인증 적용 def get_queryset(self): qs = super().get_queryset() qs = qs.filter( Q(author=self.request.user) #본인이 작성한 글만 볼 수 있도록 함. ) return qs 이렇습니다.구글링해봐도 대부분은 그냥 migrations 된 파일을 삭제하고 다시 migrate 하니까 해결이 되던데 저는 계속 같은 에러가 뜨네요..혹시 뭐가 원인인지 알 수 있을까요? AbstractUser 로 수정하고나서부터 이런 현상이 나타나긴 했습니다일단 ERD는 아래와 같이 나옵니다.
-
미해결Slack 클론 코딩[실시간 채팅 with React]
채팅보내기 강의중
안녕하세요 제로초님!채팅보내기 강의를 보고있는데 workspace/index.tsx에서갑자기 socket 코드 가생겼는데 강의에는 설명이 없는거 같아서 문의 남깁니다!
-
해결됨따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
다 잘 되는데 postman에서 err가 떠요
처음엔 config.mongoURI를 못 읽어와서 mongoDB연결이 안 되더니, console.log한 번 찍고 나니까 이상하게 돼요그런데 postman에서 err가 뜹니다..이유가 뭘까요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Application > Cookies 에 front에만 저장이 안 돼요...
안녕하세요 제로초님,Application > Cookies 에 sid가 front에만 저장이 안 되는 문제가 있습니다. sid가 back에는 저장이 됩니다.제가 아직 쿠키와 세션 이해가 부족한 건지.. axios config에 뭔가 문제가 있는건지,,, 구글링 해봐도 별 거 안 나오고.. 제가 이미 다 한 거고...https://stackoverflow.com/questions/71036779/cookies-sent-from-backend-but-not-set-correctly-on-frontendhttps://stackoverflow.com/questions/72105765/axios-doesnt-create-a-cookie-even-though-set-cookie-header-is-therefront: config/config.tsimport axios from "axios"; import { backUrl } from "../../config/config"; axios.defaults.baseURL = backUrl; axios.defaults.withCredentials = true; const instance = axios.create({ baseURL: backUrl, // cors withCredentials: true, // cookie (user info) }); // instance.interceptors.request.use(function (instance) { // const kakao_authorization = localStorage.getItem("kakao_authorization"); // const Token = localStorage.getItem("Authorization"); // const Retoken = localStorage.getItem("refresh-Token"); // instance.headers["Authorization"] = Token; // instance.headers["refresh-Token"] = Retoken; // instance.headers["kakao_authorization"] = kakao_authorization; // return instance; // }); export default instance; front - Network 탭front - Application > Cookies 탭back: app.jsconst express = require('express'); const morgan = require('morgan'); const cors = require('cors'); const session = require('express-session'); const cookieParser = require('cookie-parser'); const passport = require('passport'); const dotenv = require('dotenv'); const path = require('path'); const hpp = require('hpp'); const helmet = require('helmet'); const userRouter = require('./routes/user'); const postRouter = require('./routes/post'); const postsRouter = require('./routes/posts'); const db = require('./models'); const passportConfig = require('./passport'); dotenv.config(); const app = express(); db.sequelize.sync() .then(()=>{ console.log('db 연결 성공'); }) .catch(console.error); passportConfig(); app.use(express.json()); // axios로 data보낼 때 app.use('/', express.static(path.join(__dirname, 'uploads'))); // multipart form data app.use(express.urlencoded({ extended: true })); // 일반 form 일 때에는 url encoded로 받음 if (process.env.NODE_ENV === 'production') { app.use(morgan('combined')); app.use(hpp()); app.use(helmet({ contentSecurityPolicy: false })); app.use(cors({ origin: 'http://shinyoungyou.com', credentials: true, })); } else { app.use(morgan('dev')); app.use(cors({ origin: true, credentials: true, })); } app.use(cookieParser(process.env.COOKIE_SECRET)); app.use(session({ saveUninitialized: false, resave: false, secret: process.env.COOKIE_SECRET, cookie: { httpOnly: true, secure: false }, domain: process.env.NODE_ENV === 'production' && '.shinyoungyou.com' })); app.use(passport.initialize()); app.use(passport.session()); app.get('/', (req, res) => { res.send('Express + TypeScript Server'); }); app.post('/api/post', (req, res) => { res.send('this is post http method'); }); app.use("/user", userRouter); app.use("/post", postRouter); app.use("/posts", postsRouter); module.exports = app; back - Application > Cookies 탭
-
미해결풀스택 리액트 라이브코딩 - 간단한 쇼핑몰 만들기
caught Error: No QueryClient set, use ueryClientProvider 에러
저는 .routes 파일이 생성이 되지않아서 그냥 진행했습니다. 라우터는 잘 작동하더라구요.App에서 elem 대신 <ProductList> 를 감싸줬습니다. ProductList 에 데이터를 불러오는 과정에서 "caught Error: No QueryClient set, use ueryClientProvider to set one at useQueryClient2 " 라는 오류가 뜹니다. 데이터는 불러와지기는 합니다만 구글에 검색해보니 컴포넌트를 <QueryClientProvider > 로 감싸주면 오류가 해결된다고 하지만 저는 다른 이유인것 같습니다. 깃주소 : https://github.com/ssmv713/shopping-mall2.git
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
6-15 const store에 대해
안녕하세요영상을 따라 코드를 쭉 따라가는데요.따라치면은, 결국은 onCreate, onEdit, onRemove가 안되는데, 올려주신 최종소스에는 const store = { data, };이부분과<DiaryStateContext.Provider value={store}>이부분이 있는데,영상에는 빠져있어서 연결부분을 모르겠습니다. 영상과 최종 소스와의 차이점을 좀 알려주세요~
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
6-15에서 일기 생성이 안되는 것 같은데요.
안녕하세요올려주신 샘플에서도, 제가 직접 친 코드에서도일기 생성이 안되는 것 같은데요.알려주세요~ https://codesandbox.io/s/chapt-15-rlyyu?file=/src/App.css 자답:const handleAddButtonClick = () => {alert("일기가 추가되었어요!");return;이렇게 되어 있었네요. return을 없애니 추가 됩니다.
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 유튜브 사이트 만들기
아예 몽고DB에 연결한다고만 하고 연결이 안되고 있습니다.
> npm run dev > react-boiler-plate@1.0.0 dev > concurrently "npm run backend" "npm run start --prefix client" [1] [1] > client@0.1.0 start [1] > react-scripts start [1] [0] [0] > react-boiler-plate@1.0.0 backend [0] > nodemon server/index.js [0] [1] 'react-scripts'��(��) ���� �Ǵ� �ܺ� ����, ������ �� �ִ� ���α�, �Ǵ� [1] ��ġ ������ �ƴմϴ�. [1] npm run start --prefix client exited with code 1 [0] [nodemon] 2.0.22 [0] [nodemon] to restart at any time, enter `rs` [0] [nodemon] watching path(s): *.* [0] [nodemon] watching extensions: js,mjs,json [0] [nodemon] starting `node server/index.js` [0] Server Listening on 5000 [0] (node:9644) [DEP0170] DeprecationWarning: The URL mongodb://hwangjyoung27:tf933725@ac-xjv9w4y-shard-00-02.gefw08m.mongodb.net:27017,ac-xjv9w4y-shard-00-00.gefw08m.mongodb.net:27017,ac-xjv9w4y-shard-00-01.gefw08m.mongodb.net:27017/?authSource=admin&replicaSet=atlas-9r8jq0-shard-0&retryWrites=true&w=majority&ssl=true is invalid. Future versions of Node.js will throw an error. [0] (Use `node --trace-deprecation ...` to show where the warning was created) [0] MongoDB Connected...
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
리액트 globals.css가 원래 적용이 안되는건가요?
게시물 등록 실습중이던 학생입니다.input 크기를 잡을 때 padding값을 주어서 크기를 잡고 있었는데 미묘하게 input 태그들 마다 가로길이가 다릅니다..ㅠㅠ(컴포넌트 분리한 상태입니다.)globals.css내부를 보니 *{box-sizing:border-box} 이 ,기재되어있는거같은데 실제로는 적용이 안되는거 같습니다. padding으로 크기를 잡는게 아닌건가요? 아니면 globals에 있는 스타일이 원래 적용이 안되는건가요? 따로 작업을 해주어야하는게 있을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
로그인, 로그아웃 시 문제
안녕하세요,로그인과 마이페이지를 구현하였고,로그인 후에 router.push로 페이지 이동하고거기서 다시 마이페이지를 눌렀을때 로그인이 안되었다고 hoc에서 걸립니다.로그아웃도 마찬가지로 문제가 발생됩니다.다만, 새로고침을 했을땐 정상적으로 작동이 잘 됩니다.fetchUser 받아올 때의 문제인건지accessToken과 refreshToken에서의 api 문제인건지도저히 혼자서 해결이 어려워 문의 남깁니다..
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
node. app.js 실행시 error 발생.
안녕하세요!models 구성하고, app.js 로 db import도 다 했는데, node app.js 실행하면 다음과 같은 에러 메세지가 뜹니다.Post.belongsToMany called with something that's not a subclass of Sequelize.Modelmodels에서 user, hashtag export 가 잘못된거 같아서 다 확인했는데, 문제를 못찾았습니다.어떤 부분이 잘 못된걸까요?감사합니다.
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
로그인시 LOG_IN_REQUEST 부분
이와 비슷한 문제가 많아서 참고해서 복붙도 해보면서 했는데도 해결되지 않아질문 남깁니다. 로그인 버튼을 누르면 리덕스 데브툴에이와 같이 나오고 saga가 연결이 되지 않는 거 같아요(코드 첨부)sagas/index.jsimport { all, fork } from 'redux-saga/effects'; // import postSaga from './post'; import userSaga from './user'; export default function* rootSaga() { console.log('rootSaga') yield all([ fork(userSaga), // fork(postSaga), ]); } sagas/user.jsimport { all } from "axios"; import { delay, fork, put, takeLatest } from "redux-saga/effects"; import { LOG_IN_FAILURE, LOG_IN_REQUEST, LOG_IN_SUCCESS, LOG_OUT_FAILURE, LOG_OUT_REQUEST, LOG_OUT_SUCCESS } from "../reducers/user"; // function logInApi(data) { // // 비동기 처리 함수는 일반함수로 정의 // return axios.post("api/login", data); // } // function logOutApi() { // // 비동기 처리 함수는 일반함수로 정의 // return axios.post("api/login"); // } function* logIn(action) { console.log('login') try { console.log('saga logIn'); // const result = yield call(logInApi, action.data); //요청의 결과 yield delay(1000); yield put({ type: LOG_IN_SUCCESS, data: action.data, }); } catch (err) { console.error(err); yield put({ type: LOG_IN_FAILURE, data: err.response.data, }); } } function* logOut() { console.log('login') try { // const result = yield call(logOutApi); //요청의 결과 yield delay(1000); yield put({ type: LOG_OUT_SUCCESS, }); } catch (err) { console.error(err); yield put({ type: LOG_OUT_FAILURE, data: err.response.data, }); } } function* watchLogIn() { console.log('watchLogIn') yield takeLatest(LOG_IN_REQUEST, logIn); } function* watchLogOUT() { console.log('watchLogOUT') yield takeLatest(LOG_OUT_REQUEST, logOut); } export default function* userSaga() { yield all([ fork(watchLogIn), fork(watchLogOUT) ]) } const g = watchLogIn(); console.log(g.next())sagas/posts.js import { all } from "axios"; import { delay, fork, put, takeEvery } from "redux-saga/effects"; // function addPostsApi(data) { // // 비동기 처리 함수는 일반함수로 정의 // return axios.post("api/login", data); // } function* addPosts(action) { console.log('addPosts') try { // const result = yield call(addPostsApi, action.data); //요청의 결과 yield delay(1000); yield put({ type: "ADD_POST_SUCESS", data: action.data, }); } catch (err) { yield put({ type: "ADD_POST_FAILURE", data: err.response.data, }); } } function* watchAddPost() { yield takeEvery("ADD_POST_REQUEST", addPosts); } export default function* postSaga() { yield all([fork(watchAddPost)]); } reducers/index.jsimport { HYDRATE } from "next-redux-wrapper"; import { combineReducers } from "redux"; import user from "./user"; import post from "./post"; // (이전 상태, 액션) => 다음 상태 const rootReducer = combineReducers({ index: (state = {}, action) => { switch (action.type) { case HYDRATE: console.log("HYDRATE", action); return { ...state, ...action.payload }; default: return state; } }, user, post, }); export default rootReducer; reducers/user.jsexport const initialState = { isLoggingIn: false, //로그인 시도(로딩)중 isLoggedIn: false, // 로그인된 상태 isLoggingOut: false, // 로그아웃 시도(로딩)중 me: null, //내정보 signUpData: {}, loginData: {}, }; export const LOG_IN_REQUEST = 'LOG_IN_REQUEST'; export const LOG_IN_SUCCESS = 'LOG_IN_SUCCESS'; export const LOG_IN_FAILURE = 'LOG_IN_FAILURE'; export const LOG_OUT_REQUEST = 'LOG_OUT_REQUEST'; export const LOG_OUT_SUCCESS = 'LOG_OUT_SUCCESS'; export const LOG_OUT_FAILURE = 'LOG_OUT_FAILURE'; export const loginRequestAction = (data) => ({ type: LOG_IN_REQUEST, data }); export const logOutRequestAction = () => ({ type: LOG_OUT_REQUEST, }); const user = (state = initialState, action) => { switch (action.type) { case LOG_IN_REQUEST: console.log('reducer login') return { ...state, isLoggingIn: true, }; case LOG_IN_SUCCESS: return { ...state, isLoggingIn: false, isLoggedIn: true, me: {...action.data, nickname: 'skylove1004'}, }; case LOG_IN_FAILURE: return { ...state, isLoggingIn: false, isLoggedIn: false, }; case LOG_OUT_REQUEST: return { ...state, isLoggingOut: true, }; case LOG_OUT_SUCCESS: return { ...state, isLoggingOut: false, isLoggedIn: false, me: null, }; case LOG_OUT_FAILURE: return { ...state, isLoggingOut: false, }; default: return state; } }; export const userState = (state) => state.user; export default user;reducers/post.jsexport const initialState = { mainPosts: [ { id: 1, User: { id: 1, nickname: "skyblue5030", }, content: "첫 번째 게시글 #express #react", Images: [ { src: "https://bookthumb-phinf.pstatic.net/cover/137/995/13799585.jpg?udate=20180726", }, { src: "https://gimg.gilbut.co.kr/book/BN001958/rn_view_BN001958.jpg", }, { src: "https://gimg.gilbut.co.kr/book/BN001998/rn_view_BN001998.jpg", }, ], Comments: [ { User: { nickname: "nero", }, content: "우와 개정판이 나왔군요~", }, { User: { nickname: "hero", }, content: "얼른 사고싶어요~", }, ], }, ], imagePaths: [], //이미지업로드시 추가됨 postAdded: false, }; const ADD_POST = "ADD_POST"; export const addPost = { type: ADD_POST, }; const dummyPost = { id: 2, content: "더미데이터입니다.", User: { id: 1, nickname: "제로초", }, Images: [], Comments: [], }; // 데이터를 먼저 구성, 화면은 작성한 데이터나 데이터 변경을 기준으로 구성 // 데이터 구조는 서버측과 합의해서 구성해야 나중에 수정할 일이 없음 const post = (state = initialState, action) => { switch (action.type) { case 'ADD_POST_SUCCESS': return { ...state, mainPosts: [dummyPost, ...state.mainPosts], // 데이터을 앞에 추가해서 게시글이 위로 올라가게 postAdded: true, }; default: return state; } }; export const postState = (state) => state.post; export default post; store/configureStore.js import { applyMiddleware, compose, createStore } from "redux"; import createSagaMiddleware from "redux-saga"; import { createWrapper } from "next-redux-wrapper"; import { composeWithDevTools } from "redux-devtools-extension"; import reducer from "../reducers"; import rootSaga from "../sagas"; const loggerMidddleware = ({ getState }) => (next) => (action) => { console.log({ action, getState }); return next(action); }; const configureStore = () => { const sagaMiddleware = createSagaMiddleware(); const middlewares = [sagaMiddleware, loggerMidddleware]; const enhancer = process.env.NODE_ENV === "production" ? compose(applyMiddleware(...middlewares)) : composeWithDevTools(applyMiddleware(...middlewares)); const store = createStore(reducer, enhancer); store.sagaTask = sagaMiddleware.run(rootSaga); return store; }; const wrapper = createWrapper(configureStore, { debug: process.env.NODE_ENV === "development", }); export default wrapper;
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
로그아웃 하고 로그인 할 때 좋아요 기능 실행되는 문제
안녕하세요 제로초님! 게시글 좋아요 부분 듣고 다시 작성해보고 있는데처음 로딩 시에는 좋아요 버튼 눌렀을 때 로그인 하지 않은 상태면 에러 메시지가 잘 나오는데 ( 로그인 안 하면 좋아요 못 누르게)첫 번째 문제는 로그인 했다가 로그아웃을 한 뒤에 좋아요 버튼을 누르면 화면에는 변화가 없지만 리덕스에는 LIKE_POST_REQUEST -> LIKE_POST_SUCCESS가 되어서 이전에 로그인했던 사용자의 아이디가 LIKERS에 들어갑니다.// middlewares.js exports.isLoggedIn = (req, res, next) => { if (req.isAuthenticated()) { next(); } else { res.status(401).send('로그인이 필요합니다.'); } }여기 middlewares에 콘솔을 띄어보니 로그인 했다가 로그아웃을 한 상태에서 버튼을 누르면 401에러 부분이 아니라 if ( req.isAuthenticated()) 부분이 실행됩니다.!! // 에러 메시지 출력부분 PostCard.js// PostCard.js const { removePostLoading, likePostError } = useSelector((state) => state.post); useEffect(() => { if (likePostError) { alert(likePostError); } }, [likePostError]);// routes/user.js - 로그아웃 부분router.post('/logout', isLoggedIn, (req, res, next) => { req.logout((err) => { if (err) { return next(err); } }); req.session.destroy(); res.send('ok'); });
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
질문있어요.
setting.jason이 그냥 비어있던데 강사님처럼 똑같이 타이핑 후 3줄을 적어야하나요? 아니면 3줄만 입력하면 되나요?강사님처럼 똑같이 입력해야한다면, 3줄 중 마지막 한줄이 중복되는데 어떻게 하나요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
메인페이지에서 fetchBoardsOfTheBest 질문입니다.
(위 화면은 fetchBoardsOfTheBest에서 images을 보여주는 파일입니다) 메인화면 하다가 질문이 있어서 글 남깁니다.API fetchBoardsOfTheBest에서 images 부분에 0번째는 0: "codecamp-file-storage/2023/4/18/copy-1616378722-5.jpg"이런식으로 뜨고1번째는 0: "https://storage.googleapis.com/codecamp-file-storage/2023/5/2/SampleJPGImage_100kbmb.jpg"1: "https://storage.googleapis.com/codecamp-file-storage/2023/5/2/file_example_JPG_100kB.jpg"이렇게 두개가 뜹니다.. 저희가 여태 배웠던 BoardDetail.presenter에서는 src={`https://storage.googleapis.com/${el}`} 이런식으로 주소를 주어서 사진을 가져왔는데 fetchBoardsOfTheBest 의 이미지는 src=" ? " 어떻게 가져와야할까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
openWeartherMap - fetch()부분
강의 영상에서 https:// 해당 부분 에서 3.0을 2.5로 바꿔서 수정하면 오류가 해결된다고 하셨는데 적용 시켜봐도 오류가 계속 유지 됩니다
-
미해결Slack 클론 코딩[실시간 채팅 with React]
str.toLowerCase is not a function
예상하지 못한 부분에서 에러가 나와서 질문 남겨드립니다 !ChatBox.tsximport React, { useCallback, useEffect, useRef, VFC } from 'react'; import { ChatArea, EachMention, Form, MentionsTextarea, SendButton, Toolbox } from './styles'; import autosize from 'autosize'; import { Mention, SuggestionDataItem } from 'react-mentions'; import { useParams } from 'react-router'; import useSWR from 'swr'; import { IUser } from '@typings/db'; import fetcher from '@utils/fetcher'; import gravatar from 'gravatar'; interface Props { chat: string; onSubmitForm: (e: any) => void; onChangeChat: (e: any) => void; placeholder?: string; } const ChatBox: VFC<Props> = ({ chat, onSubmitForm, onChangeChat, placeholder }) => { const { workspace } = useParams<{ workspace: string }>(); const { data: userData, error, revalidate, mutate, } = useSWR<IUser | false>('/api/users', fetcher, { dedupingInterval: 2000, // 2초 }); const { data: memberData } = useSWR<IUser[]>(userData ? `/api/workspaces/${workspace}/members` : null, fetcher); 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], ); const renderSuggestion = useCallback( ( suggestion: SuggestionDataItem, search: string, highlightedDisplay: React.ReactNode, index: number, focus: boolean, ): React.ReactNode => { if (!memberData) return; return ( <EachMention focus={focus}> <img src={gravatar.url(memberData[index].email, { s: '20px', d: 'retro' })} alt={memberData[index].nickname} /> <span>{highlightedDisplay}</span> </EachMention> ); }, [memberData], ); return ( <ChatArea> <Form onSubmit={onSubmitForm}> <MentionsTextarea id="editor-chat" value={chat} onChange={onChangeChat} onKeyPress={onKeydownChat} placeholder={placeholder} inputRef={textareaRef} allowSuggestionsAboveCursor > <Mention appendSpaceOnAdd trigger="@" data={memberData?.map((v) => ({ id: v.id, display: v.nickname })) || []} renderSuggestion={renderSuggestion} /> </MentionsTextarea> <Toolbox> <SendButton className={ 'c-button-unstyled c-icon_button c-icon_button--light c-icon_button--size_medium c-texty_input__button c-texty_input__button--send' + (chat?.trim() ? '' : ' c-texty_input__button--disabled') } data-qa="texty_send_button" aria-label="Send message" data-sk="tooltip_parent" type="submit" disabled={!chat?.trim()} > <i className="c-icon c-icon--paperplane-filled" aria-hidden="true" /> </SendButton> </Toolbox> </Form> </ChatArea> ); }; export default ChatBox;혼자서 해결해보려다가 못찾고 있어서 질문 남겨드려요 ㅠㅠ