묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[리액트 2부] 고급 주제와 훅
[4.4장 메모이제이션 훅] 4.4.3 memo 참조 비교
안녕하세요. 강사님! 학습 중에 궁금한 점이 생겼는데, 제가 이해하고 있는 내용이 맞는지 궁금해 질문 드립니다!const obj1 = { a: 1 }; const obj2 = { a: 1 }; const obj3 = obj1; console.log(obj1 === obj2); // falseconsole.log(obj1 === obj3); // true 자바스크립트에서 객체나 배열을 비교할 때 기본적으로 참조를 비교하는 것으로 알고 있습니다. 즉, 1번에서 두 객체가 같은 값을 가지고 있으나 메모리 주소가 달라 false를 출력하고,2번에선 같은 메모리 주소를 참조해 true를 출력하는 것으로 알고 있습니다여기서부터 제가 궁금했던 내용입니다!캐시된 filteredPosts를 사용해 렌더링하는 경우를 가정했을 때 :const filteredPosts = MyReact.useMemo(filterPosts, [posts, tag]);filteredPosts는 useMemo를 통해 filterPosts 함수로 생성된 배열을 클로저 공간에 넣어두고, posts와 tag가 변경되지 않는다면 항상 똑같은 값을 FilteredPosts로 전달 =><FilteredPosts posts={filteredPosts} /> const FilteredPosts = MyReact.memo(({ posts }) => { ... } // FilteredPosts는 캐시된 filteredPosts를 memo 함수로 전달 =>function memo(TargetComponent) { return (nextProps) => { ... const [prevValue, prevProps] = TargetComponenet.memorizedState; if (prevProps === nextProps) { return prevValue; } ... } }그럼 여기 전달된 nextProps(캐시된 filteredProps)는 당연히 같은 메모리를 참조하니 깊은 비교 없이 참조 비교만으로도 비교가 가능하지 않나? 싶었습니다.filteredPosts는 결과적으로 useMemo로 캐시되어있고, 새로 생성된 배열이 아니니 메모리 주소가 동일해 prevValue가 리턴되지 않을까? 했는데 아니더라구요..useMemo를 통해 filteredPosts 배열의 참조는 동일하게 유지되고 있는건 맞는데,{ posts: filteredPosts }이렇게 FilteredPosts 컴포넌트에 전달되는 props 객체가 매번 새로운 객체로 생성돼서 그런건가? 싶은데 이게 맞는지 궁금해서 질문 드립니다..
-
미해결[리액트 2부] 고급 주제와 훅
useRef 관련하여 질문드립니다
MyReact.useRef관련하여 질문드립니다const ref2 = MyReact.useRef();<input ref={ref}/> 이렇게 사용하면input태그에 접근할 수 있는데 정확히 어떤 원리로 접근 가능한건가요??ref2는 원래 undefined값이 아닌가요?
-
미해결[리액트 2부] 고급 주제와 훅
렌더 프롭 관련하여 질문드립니다
컨텍스르를 설계하실 때 const Consumer = ({childeren } => <>{children(emiiter.get())}</>) 설명하시면서 렌더프롭이라고 설명하셨습니다.그 이후 Count 설계하실 때 {(value) => <div>{value.count}</div>} 라고 적으셨는데 렌드 프롭에 대한 설명이 없으셔서 정확히 어떻게 렌더링되는지 궁금합니다!! 정확한 원리를 자세히 모르겠습니다
-
미해결[리액트 2부] 고급 주제와 훅
[1.2장 상품목록 화면] 1.2.3 Button ...rest 관련 질문 드립니다.
안녕하세요. 아래 질문에 대한 답글을 보고 …rest에 대해 이해를 했는데요.https://www.inflearn.com/questions/1186424 몇 가지 궁금한 점이 생겨 질문 드립니다! 강의에서 나온 방식이 1번 어트리뷰트로 버튼 컴포넌트에 인자를 전달하는 것 맞을까요?App.jsx<Button styleType={"brand"} onClick={() => console.log("TODO: 주문하기 클릭")} > 주문하기 </Button>Button.jsxconst Button = ({ styleType, block, ...rest }) => { let className = 'Button'; if (styleType) className += ` ${styleType}`; if (block) className += ` block`; return <button className={className} {...rest}/> }; export default Button; 위 App.jsx의 Button에 대한 JSX 코드를 JS 코드로 변환하면 아래와 같이 변환 되나요? onClick은 어떤 식으로 변환되는지 궁금합니다. createElement( Button, // 함수 { styleType: "brand" }, // props onClick: () => console.log("TODO: 주문하기 클릭") // children "주문하기 , 결제하기" // children ) onClick도 …rest 나머지 매개변수 구문에 들어갔는데, 개발자 도구에서 props를 보면 onClick은 onClick이라는 프롭스에 맵핑 되어 있습니다. rest 객체에 children, onClick 속성이 포함되어 있어서 내부적으로 구분해주는 것인가요?아래처럼 작성 하는 게 2번 태그 안에 인자를 전달하는 방식 맞을까요? <Button styleType={"brand"} onClick={() => console.log("TODO: 주문하기 클릭")} children={"주문하기"} > </Button> 감사합니다.
-
미해결[리액트 2부] 고급 주제와 훅
[4.4장 메모이제이션 훅] 4.4.4 useCallback curried function에 관한 질문입니다.
안녕하세요 선생님 질문이 2개 있습니다. const handleClick1 = MyReact.useMemo((postId) => { console.log("handleClick", postId); }, []); const handleClick2 = MyReact.useMemo(() => (postId) => { console.log("handleClick", postId); }, []);double arrow function을 curried function이라고 하던데 이번 예시에서 MyReact.useMemo를 쓰는 경우에는 1) handClick1, handClick2 둘 다 상관이 없나요?2) 있다면 무슨 이점때문에 handleClick2처럼 쓰신건가요?
-
해결됨[리액트 2부] 고급 주제와 훅
[4.4장 메모이제이션 훅] 4.4.2 useMemo 에서 every 함수에 관한 질문입니다.
안녕하세요 선생님 every 배열을 비교하는 방법이 궁금해서 로그를 찍어보았습니다.// export default App; import MyReact from "./lib/MyReact"; import React from "react"; const Board = ({ posts, tag }) => { MyReact.resetCursor(); const [darkTheme, setDarkTheme] = React.useState(false); const filterPosts = () => { console.log("filterPosts"); return posts.filter((post) => (tag ? post.tag === tag : true)); }; const filteredPosts = MyReact.useMemo(filterPosts, [posts, tag]); console.log("Board rendered"); return ( <> <div> <button onClick={() => setDarkTheme(!darkTheme)}>Theme Change</button> <span>{darkTheme ? "dark" : "light"}</span> </div> <FilteredPosts value={filteredPosts}></FilteredPosts> </> ); }; const FilteredPosts = MyReact.memo(({ value }) => { console.log("FilteredPosts rendered") return ( <ul> {value.map(({ id, content, tag }) => { return ( <li key={id}> {content} <span>#{tag}</span> </li> ); })} </ul> ); }); export default () => { const [tag, setTag] = React.useState(""); return ( <> <button onClick={() => setTag("")}>ALL</button> <button onClick={() => setTag("tag1")}>Tag1</button> <button onClick={() => setTag("tag2")}>Tag2</button> <Board posts={[ { id: "id1", content: "content1", tag: "tag1" }, { id: "id2", content: "content2", tag: "tag1" }, { id: "id3", content: "content3", tag: "tag2" }, ]} tag={tag} /> </> ); }; function useMemo(nextCreate, deps) { console.log("deps = ", deps); if (!memorizedStates[cursor]) { const nextValue = nextCreate(); memorizedStates[cursor] = [nextValue, deps]; cursor = cursor + 1; return nextValue; } const nextDeps = deps; const [prevValue, prevDeps] = memorizedStates[cursor]; console.log("prevDeps => ", prevDeps); console.log("nextDeps => ", nextDeps); if ( prevDeps.every((prev, index) => { console.log( "comparing -> ", prev, nextDeps[index], prev === nextDeps[index], index ); return prev === nextDeps[index]; }) ) { console.log("it is same"); cursor = cursor + 1; return prevValue; } console.log("it is not same"); const nextValue = nextCreate(); memorizedStates[cursor] = [nextValue, deps]; cursor = cursor + 1; return nextValue; }여기서 궁금한 점은1번째 빨간 paragraph는 theme change를 눌러서 변경이 없는 경우입니다. comparing => 로그를 확인하면every가 2개를 비교하는데 첫번째는 array(posts)를 비교하고두번째는 tag를 비교하는것을 확인 할 수 있습니다. 2번째 빨간 paragraph는 Tag1 버튼을 누른 경우입니다.이때 저는 첫번째 비교는 true이고 두번째 비교에서 빈문자열 vs tag1이니 여기서 false가 나길 기대했지만 결과는 그렇지 않았고 첫번째 array(posts) 비교에서 false가 나왔습니다. 3번째 빨간 paragraph는 다시 theme change를 눌렀고 이는 정상적으로 array(posts) , tag1 비교를 수행한것을 확인할 수 있습니다. 왜 이런것인가요?
-
미해결[리액트 2부] 고급 주제와 훅
[4.3장 리듀서 훅] 4.3.7 활용 MyForm(풀이) 오타 제보 및 질문이 있습니다.
안녕하세요 선생님 코드에 오타가 있습니다.const formReducer = (state, action) => { if (action.type === "SET_VALUES") { console.log("SET_VALUES, state ", state); return { ...state, values: { ...state.values, //value --> values [action.name]: action.value, }, }; }value에서 values로 수정되어야 할 것 같습니다. 질문:1) value 인 상태에서는 전화번호에 숫자를 입력했을 때 onChange event에 의해서 state가 변경이 됨2) 이때 state.value는 undefined 이라 기존에 주소 값에 적어뒀던 "123" 이 무시되고 전화번호 값만 action에 의해서 state에 저장.3) useEffect가 state 변경을 감지하고 validate를 진행후에 reducer의 forceupdate 에 의해 re render 4)주소값이 없었으니 errorr값에 "주소를 입력하세요" 들어있다.라고 이해하면 맞을까요?
-
해결됨[리액트 2부] 고급 주제와 훅
[4.1장 레프 훅] useRef관련 질문이있습니다.
안녕하세요 선생님 본 강의 예시에서import MyReact from "./lib/MyReact"; import React from "react"; export default () => { const ref1 = MyReact.useRef(1); const ref2 = MyReact.useRef(); const [state, setState] = React.useState(0); console.log(state) if (state > 2) { console.log("hihi"); ref1.current = ref1.current + 1; } return ( <> <button onClick={() => setState(state + 1)}> state increase (state: {state}) </button> <div>{ref1.current}</div> <input ref={ref2}></input> <button onClick={() => console.log("input value", ref2.current.value)}> ref2 select </button> </> ); };state >2 이면 값이 증가하는것을 확인했는데 이후에도 계속 state가 2 초과 이니까 계속 ref1.current가 증가할 줄 알았는데 아니더라구요 왜그런건가요?
-
미해결[리액트 2부] 고급 주제와 훅
[1.3장 주문 내역 화면] 1.3.5 Card 조합 질문 있습니다
강의를 듣다가 의문이 생겨서 질문 드립니다.const OrderPage = () => ( <div className="OrderPage"> <Page header={<Title>주문내역</Title>} footer={<Navbar />}> <OrderStatusCard order={fakeOrder} /> <OrderPaymentCard order={fakeOrder} /> <OrderDeliveryCard order={fakeOrder} /> </Page> </div> );위 코드는 수업중 강사님이 작성하신 코드 입니다.제가 의문인 부분은 OrderStatusCard, OrderPaymentCard, OrderDeliveryCard 모두 같은 fakeOrder를 파라미터로 넘기는 점 입니다.fakeOrder는 Order가 발생될 때 생기는 모든 데이터를 저장하고 있습니다.이때 OrderStatusCard 관점에서 보면 Status와 상관 없는 데이터들도 fakeOrder를 받으면서 같이 파라미터로 넘어가게 됩니다.(예를 들어 deliveryPrice, discountPrice 등 배달에 관련 데이터가 같이 넘어갑니다.)해당 실습 예제 코드는 적은 데이터를 사용해서 문제가 없겠지만 만약 수 많은 데이터가 한번에 오고 갈때 성능적인 이슈가 발생하는 문제와 status와 상관없는 데이터들이 넘어가 컴포넌트들이 완벽하게 분리 되지 않는 느낌이 있습니다.제가 생각한 방법은 조금 귀찮더라도 Order정보를 가지고 있는 OrderPage에서 데이터를 분리해서 넘겨주는 것이 좋다고 생각합니다.아래는 제가 작성한 코드입니다.const OrderPage = () => ( <div className="OrderPage"> <Page header={<Title>주문내역</Title>} footer={<Navbar />}> <OrderStatusCard status={fakeOrder.status} orderDate={fakeOrder.orderDate} name={fakeOrder.name} id={fakeOrder.id} /> <OrderPaymentCard totalPrice={fakeOrder.totalPrice} paymentMethod={fakeOrder.paymentMethod} productPrice={fakeOrder.productPrice} deliveryPrice={fakeOrder.deliveryPrice} discountPrice={fakeOrder.discountPrice} /> <OrderDeliveryCard deliveryAddress={fakeOrder.deliveryAddress} deliveryContact={fakeOrder.deliveryContact} messageToRider={fakeOrder.messageToRider} messageToShop={fakeOrder.messageToShop} /> </Page> </div> );현업에서는 어떤 방식을 사용하는지 강사님의 의견을 듣고 싶습니다. 좋은 강의 잘 듣고 있습니다. 긴글 읽어주셔서 감사합니다 ㅎㅎ
-
해결됨[리액트 2부] 고급 주제와 훅
[3.5장 컨택스트 훅] 3.5.2 useContenxt 에서 질문이 있습니다.
안녕하세요 선생님 Count, PlusButton이 re render 되는 조건을 알고 싶습니다. 예전예시에서는 class Consumer extends React.Component { constructor(props) { super(props); this.state = { value: emitter.get(), }; this.setValue = this.setValue.bind(this); } setValue(nextValue) { this.setState({ value: nextValue }); } componentDidMount() { emitter.on(this.setValue); } componentWillUnmount() { emitter.off(this.setValue); } render() { return <>{this.props.children(this.state.value)}</>; } } Consumer가 state를 가지고 있음으로순서가Provider render -> Consumer render -> Consumer componentDidMount -> Provider componentDidMount (set 을 통해 빈 객체였던 것을 value, setValue로 바꿔줌)이때 Consumer state는 emitter.get()임으로 변경된 것을 감지 하고 re render 하는 것으로 이해했었습니다.헌데 이번예시에서는 function useContext(context) { console.log("userContext, context.emitter.get() = ", context.emitter.get()); const [value, setValue] = React.useState(context.emitter.get()); React.useEffect(() => { console.log("Consumer useEffect"); context.emitter.on(setValue); return () => { console.log("Consumer useEffect clean"); context.emitter.off(setValue); }; }, [context]); return value; } const Count = () => { console.log("Count render"); const { count } = MyReact.useContext(countContext); return <div>{count}</div>; };Provider render -> Count(Consumer) render -> Count's useEffect -> Provider's useEffect 을 통해emitter 값이 빈객체에서 count, setCount로 채워지는것은 이해하였습니다.이때 Count 가 다시 한번 re render되는데 왜 그런 것인가요?첫번째 예시처럼 state?같은게 존재하는건가요?다시 render되는 조건이 궁금합니다.
-
미해결[리액트 2부] 고급 주제와 훅
[1.3.6 상태정의] state 관련
OrderPage/index.jsx 생성자(constructor)의 state 부문에서 this.state = {order: null,} 와 this.state = {}의 차이가 있나요?(this.state = {order: null,} 로 선언한 이유가 궁금합니다. )
-
해결됨[리액트 2부] 고급 주제와 훅
[2.4장 다이얼로그 1] 2.4.5 withLayout(풀이) 에 관한 질문입니다.
안녕하세요 선생님 혼자 해보는 과정중에 질문이 있습니다.import React from "react"; import Backdrop from "../components/Backdrop"; import Dialog from "../components/Dialog"; export const layoutContext = React.createContext({}); layoutContext.displayName = "LayoutContext"; export class Layout extends React.Component { constructor(props) { super(props); this.state = { dialog: null, }; this.setDialog = this.setDialog.bind(this); } setDialog(dialog) { this.setState({ dialog }); } render() { const value = { dialog: this.state.dialog, setDialog: this.setDialog, }; return ( <layoutContext.Provider value={value}> {this.props.children} </layoutContext.Provider> ); } } export const DialogContainer = () => ( <layoutContext.Consumer> {({ dialog }) => dialog && <Backdrop>{dialog}</Backdrop>} </layoutContext.Consumer> ); export const withLayout = (WrappedComponent) => { const WithLayout = (props) => ( <layoutContext.Consumer> {({ dialog, setDialog }) => { const openDialog = () => { console.log("openDialog") setDialog(<Dialog>hihi</Dialog>); }; const closeDialog = () => { setDialog(null); }; const enhancedProps = { openDialog, closeDialog, }; return ( <WrappedComponent {...props} {...enhancedProps}></WrappedComponent> ); }} </layoutContext.Consumer> ); return WithLayout; }; withLayout을 만들어서 openDialog, closeDialog를 enhancedProps로 전달을 하였습니다.import * as MyLayout from "../lib/MyLayout"; const Page = ({ header, children, footer, openDialog }) => ( <div className="Page"> <header>{header}</header> <main>{children}</main> <footer>{footer}</footer> <MyLayout.DialogContainer /> <button onClick={openDialog}>dialog</button> </div> ); export default MyLayout.withLayout(Page); Page에서 MyLayout.DialogContainer이 기본값이 null인데 button을 추가하여 고차컴포넌트에서 주입받은 openDialog를 사용하여 Dialog를 렌더링하는데 성공하였습니다.닫기도 해보고싶어서import * as MyLayout from "../lib/MyLayout"; const Dialog = ({ closeDialog }) => ( <div className="Dialog"> <header>header</header> <main>main</main> <footer>footer</footer> <button onClick={closeDialog}>closeDialog</button> </div> ); export default MyLayout.withLayout(Dialog);Dialog component에 닫기 버튼을 추가하려고 MyLayout.withLayout으로 감싸니초기화 전에 참조하려 했다는데 이 에러 자체는 이해가 가지만 왜 지금 위 상황이 이 에러에 해당되는 상황인지 이해가 가지 않습니다...
-
해결됨[리액트 2부] 고급 주제와 훅
[2.1장 컨택스트] 2.1.4 공급자와 소비자 / 에서 질문이 있습니다.
안녕하세요 선생님 react context를 이해하려고 시도하는 중입니다.const countContext = MyReact.createContext({ count: 0, setCount: () => {}, }); class CountProvider extends React.Component { constructor(props) { console.log("CountProvider construtor"); super(props); this.state = { count: 0, }; } render() { const value = { count: this.state.count, setCount: (nextValue) => this.setState({ count: nextValue }), }; return ( <countContext.Provider value={value}> {this.props.children} </countContext.Provider> ); } } const Count = () => { return ( <countContext.Consumer> {(value) => { console.log("CountComponent", value); return <div>{value.count}</div>; }} </countContext.Consumer> ); }; const PlusButton = () => { return ( <countContext.Consumer> {(value) => { console.log("PlustButtonComponent", value); return ( <button onClick={() => value.setCount(value.count + 1)}> + 카운트 올리기 </button> ); }} </countContext.Consumer> ); }; export default () => ( <CountProvider> <Count /> <PlusButton /> </CountProvider> );Count , Plus Button component return 문에 각각console.log("CountComponent", value); console.log("PlustButtonComponent", value);로그를 남겨봤습니다.사진에 표시 된 것 처럼 로그가 각 Component마다 2번씩 찍히는데 그 이유를 알 수 있을까요...?로그의 value 값이 다른게 힌트 같은데 해석을 하지 못하겠습니다.
-
해결됨[리액트 2부] 고급 주제와 훅
[1.4장 장바구니 화면] 1.4.9 레프와 돔 / export에 관한 질문입니다.
안녕하세요 선생님 Ref를 알아보는 과정에서import React from "react"; import CartPage from "./pages/CartPage"; import OrderPage from "./pages/OrderPage"; import ProductPage from "./pages/ProductPage"; const App = () => ( <> {/* <ProductPage /> */} {/* <OrderPage /> */} <CartPage /> </> ); // export default App; class MyComponent extends React.Component { divRef = React.createRef(); render() { return ( <div ref={this.divRef}> </div> ) } componentDidMount() { console.log(this.divRef) } } export default MyComponent 이렇게 MyComponent가 export 되었길레import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import MyComponent from "./App"; const { worker } = require("../../shared/mocks/browser"); worker.start({ onUnhandledRequest: "bypass", }); const root = ReactDOM.createRoot(document.getElementById("root")); root.render(<App />); // root.render(<MyComponent />);main.js에서 root.render를 변경해야될줄 알았는데 변경을 하지 않아도 정상동작을 하는데 이것은 왜 그런것인가요?
-
해결됨[리액트 2부] 고급 주제와 훅
[1.2장 상품목록 화면] 1.2.3 Button 에서 기본 props? 관련 질문이 있습니다.
안녕하세요 선생님 질문이 있습니다.<Button whatelse={"will"}>주문하기 , 결제하기</Button> --- const Button = ({ whatelse }) => ( <button className="Button brand">{whatelse}</button> ); export default Button;children처럼 제가 따로 설정해주지도 않았는데 기본적으로 생성된 props들은 뭐라고 부르나요? const Button = ({ styleType, block, ...rest }) => { let className = "Button"; if (styleType) className += ` ${styleType}`; if (block) className += ` block`; return <button className={className} {...rest}></button>; }; export default Button; 또한 강의 후반에 ...rest로 children, onClick props 를 퉁치는데 이떄 children props 내용이 return하는 button element에 {children} 이렇게 들어있지 않아도 잘 렌더링이 되던데 이것은 뭐라 부르나요?
-
해결됨[리액트 2부] 고급 주제와 훅
강의 수강 순서 질문 있습니다.
선생님 안녕하세요 리액트 1부 수강하고 2부로 넘어온 수강생입니다 ㅎㅎ제가 리액트 1부도 수강했고 그 외에 다른 리액트 강의도 먼저 수강한게 있는 상태에서리액트 2부 목차를 보니깐 들어보면 좋을법한 내용들이 많이 있는 것 같아서 수강신청을 했습니다.그런데 다루는 내용이 자세하고 많다보니깐 강의 시간이 많이 길어서 강의를 조금 더 효율적으로 듣는 방법을 생각해 보게 되었는데요... 현재 2부 수강은 1편은 다 수강한 상태이고 2편 3편 4편이 남았는데요요즘 리액트 개발이 함수형 컴포넌트로 많이 이루어지고 있고 저도 훅에 대한 개념이 약하다고 판단되서 수강을 하게 된 것도 있어서 훅에 대한 내용을 먼저 수강하는 게 낫지 않을까 하는 생각이 드는데요그래서 제가 3편과 4편을 모두 수강 한 뒤에 2편을 수강하려고 하는데 혹시 3편과 4편에서 다루는 내용중에 2편을 수강하지 않으면 이해가 어려운 주제들이 있을까요?? 아! 그리고 제가 2편도 컨텍스트까지는 수강했는데 대부분의 리액트 강의에서는 이렇게 치면 이런 기능을 한다. 하면서 넘어가는 것과는 달리 소개해주신 주제는 어떤 기능을 하며 그 기능을 구현하는 걸 코드를 통해 알려주셔서 더 재밌고 깊이있게 들을 수 있는 것 같아 좋은 것 같은데요 반면에 어떤 기능이 작동하는 원리를 구현하는 것이다 보니 내용이 많이 어렵게 느껴질 때가 있는데요... (2편 컨텍스트 부분은 전체 강의만 여러번 들은 것 같습니다. 원래 어려운게 맞는지 저한테만 어려운건지 잘 모르겠네요..) 그래서 제가 코드에디터에 강의 자료 블로그에 있는 코드를 보고 치면서 주석으로 설명을 쓰면서 정리를 해보면서 강의를 들으려고 하는데 혹시 블로그 자료에 있는 코드나 강의에서 설명하신 내용 정리한것을 깃허브에 올려도 될까요??
-
해결됨[리액트 2부] 고급 주제와 훅
리액트 설치 하실 때 질문 있습니다.
1부 듣고 이제 막 2부 와서 개발 환경 강의를 들었는데요혹시 리액트를 처음에 설치 하실 때 npx create-react-app 을 안쓰시고 직접 package.json을 직접 작성하신 다음에 npm i로 설치 하시나요??아니면 npx create-react-app을 하시고 나서 필요없는 파일 지우고 폴더구조나 package.json을 수정 하시는 건가요??깃 헙 저장소 가져와서 브런치 이동해보면 나오는 파일이나 폴더가 제가 npx create-react-app으로 리액트를 설치했을 때랑은 조금 다른것도 같은데 보통 다른 책이나 강의들 보면 거의 npx create-react-app으로 설치하고 진행 하는데 선생님은 어떻게 하시는지 궁금합니다... 그리고 혹시 전자의 경우로 하신다면 그렇게 하시는 이유도 궁금합니다!!
-
해결됨[리액트 2부] 고급 주제와 훅
ProductPage import 할 때, from index.jsx가 아닌 이유
안녕하세요. 강의 재밌게 듣고 있습니다! App.jsx에서 import ProductPage from "./pages/ProductPage" 부분에서 실제 코드는 index.jsx에 작성되어 있는데 디렉터리명인 ProductPage로 경로를 지정해도 동작하는 이유가 궁금합니다.
-
미해결[리액트 2부] 고급 주제와 훅
useMemo내에서 사용되는 window.location.search 를 deps에서 제외한 이유
안녕하세요. 정환님 드디어 강의도 마무리되어가는데살짝 이해가 안된 부분이 있습니다. URLSearchPrarms 를 통해 query param를 파싱하는 부분을 캐싱하는 부분에서 window.location.search 는 딱 한번만 바뀌고 거의 바뀌지않을 것이라고 이야기하셨는데 같은 페이지에서 navigate가 흔히 있는 요구사항이 아닌가요? 저희가 사용하는 Router의 useNavigate를 통해 화면간에 이동할 때마다 변하는 값으로 알아서 넣어두는게 더 이상적이라고 생각하고 실습을 진행했습니다. 저희 예제에서는 cart 페이지에서 cart로 이동할 비지니스 요구사항은 없어서 괜찮지만 예를들어 다른 상품이 담겨있는 장바구니로 이동하는 요구사항이 있다면 /cart?productId=CACDA421 => /cart?productId=CACDA423deps에 window.location.search를 넣어두는게 안전해보이는데 최적화가 필요한 부분이었을까요?
-
미해결[리액트 2부] 고급 주제와 훅
MyReact.useReducer로 Validate를 구현한 부분을 이상적으로 처리하려면?
안녕하세요. Reducer는 ReactJS에서 제공하는것을 거의 잘 안써왔었는데 한번 활용해봐야겠다는 마음이들었던 강의였습니다. 이번 4.3장(리듀서 훅) 수강하고 궁금한 부분은 Validate처리가 일반적으로 dispatch만으로 해소가 안되는 부분을 직접 reducer를 호출해줘서 처리하는 부분을 봤습니다. 직접 리듀서를 호출하는 형태가 조금 리듀서를 만든 의도와 다른 방향같기도한데. 이전상태를 이용해서 앞으로의 상태를 업데이트하고 싶을때 dispatch를 사용해야한다면 어떻게 처리되야 조금 더 이상적인 방향이라고 생각하시나요?