잘 짠건 몰라도 사용자 문제인게 대다수. provider value 에 객체 그냥 박아넣는 것도 보고 value 바뀌면 provider 자식이 다 리렌더링된다고 주장하는 글도 있더라
익명(223.62)2023-07-28 00:59
답글
다 바뀌는거아님? 적어도 랜더링 시도는 할거아녀.
익명(211.209)2023-07-28 02:40
답글
정확히말하면 Context Provider 자체의 props가 변경이 되는것을 리액트가 감지하면 룰에 의해서 아래 있는 자식들도 다 랜더링 시도하는거 아닌가 했음.
React.memo로 감싸져있거나, 변경 영향 없으면 당연히 그 아래부터는 랜더링 시도 안할거고.
익명(211.209)2023-07-28 02:42
답글
그리고 provider에 value를 그대로 안박는 케이스가 있음..? 그것도 궁금하네. 그냥 mutable한 object 껴넣고 처리하는건가?
익명(211.209)2023-07-28 02:43
답글
객체 박아넣고 reducer + dispatch로 처리하는거지뭔
아님말구(dolsom)2023-08-07 13:56
렌더링이랑 컨텍스트 관련한 오개념 ㄹㅇ 많음
익명(182.226)2023-07-28 02:19
이거 보고 이상해서 직접 react-dev-tools로 실험해봤는데 리랜더링 됨. react.memo를 쓰면 자식들 랜더링 phase를 패스하는것도 확인 함.
props가 변경되면 당연히 리랜더링 고쳐지는게 react 랜더링의 원칙인데 왜 이게 틀린가 했음.
혹시 리랜더링을 dom에 새롭게 그리는 과정으로 오해한게 아닌지..
익명(211.209)2023-07-28 03:07
답글
물론 context api를 그거 때문에 쓰지 않는다는건 좀 비약이 심하지만 (다른 이유가 더 크지만)
리액트가 워낙 랜더링 체크 퍼포먼스가 저조할 수 밖에 없는 환경이라, 이런거 챙겨주는것만해도 스크립트 로딩속도나 스크립트 처리속도 향상되는것도 맞을듯
익명(211.209)2023-07-28 03:08
답글
Provider 자식 전체가 아니라 useContext 사용한 곳에서만 렌더링 돼야 정상임. 코드 한 번 올리면 볼게. 블로그 글의 대부분의 경우 Provider 분리 안 하고 바로 App에서 Context.Prover 쓰고 App에 state 박아두는 케이스가 대부분이었음. 분리해서 children 을 props 로 받으면 Provider 내부의 state 가 변해도 children 은 props 라서 리렌더링 되지 않음.
익명(223.62)2023-07-28 06:46
답글
value에 객체 그대로 박는다는 얘기는 구체적으로 말하면 Context 를 루트에서 사용하지 케이스에서 부모가 리렌더링 되는 경우에 useMemo를 써야한다는 얘기였고
익명(223.62)2023-07-28 06:47
답글
1) 분리해서 children 을 props 로 받으면 Provider 내부의 state 가 변해도 children 은 props 라서 리렌더링 되지 않음.
=>일단 이렇게 쓰게되면 value에 그냥 객체를 받는다고 가정할게. 그럼 Provider의 value={} props가 변하니까 children은 영향을 받게 되는 셈임.
App이랑은 상관없음.
익명(211.209)2023-07-28 10:32
답글
React.memo : This memoized version of your component will usually not be re-rendered when its parent component is re-rendered as long as its props have not changed. => 다른말로 parent 의 props가 변경되면 child의 re-render가 불린다. 그러니 React.memo, shouldComponentUpdate 이런거 썼고.
익명(211.209)2023-07-28 10:46
답글
2) value에 객체 그대로 박는다는 얘기는 구체적으로 말하면 Context 를 루트에서 사용하지 케이스에서 부모가 리렌더링 되는 경우에 useMemo를 써야한다는 얘기였고
요 내용은 context 쓸 때 useMemo, useCallback 같은거 껴넣어서 최대한 props가 쓸데없이 변경되지 말자라는 의미 같은데 (특히 callback류 함수들은 이런 리랜더링에 매번 새로운 함수를 생성하니까). 그거랑 "useContext 사용한 곳에서만 렌더링 돼야 정상임" 이것과는 상관없다는것같음.
예제 감사. 예제보고 내가 예상했던것과 동작이 달라서 내가 잘못 이해한 부분이 있는 것 같아 정리해봤음. 일깨워줘서 감사. (위에 댓글 보고 오해하시는 분들 있을 것 같아서 정리)
1. React-dev-tools는 랜더링 시점 제대로 캐치 못하는듯. Profile쓰거나 아니면 컴포넌트 함수 내부에서 직접 호출하면 될 듯. (dev-tools는 위 예제도 리랜더링 되었다고 뜸)
2. Context 자체는 리랜더링과 관련이 없음. 이 부분이 내가 틀리게 알고 있던 부분인데 Context를 쓰는 패턴이 리랜더링을 부를 수 있는 거고, Context 자체는 리랜더링과 상관없음.
익명(211.209)2023-07-28 11:31
답글
3. 리랜더링 여부는 props와 state와 관련있음 만약 특정 컴포넌트가 state나 props가 변경되면 그 하위의 컴포넌트들이 리랜더링 후보가 됨. 위 예제에서는 각 컴포넌트가 애초에 props가 없으니 리랜더링 과는 관련이 없음.
4. Context가 리랜더링에 취약하다는건, 하나의 useState에 모든 데이터를 모는 경우, 혹은 하나의 useReducer로 모든 데이터를 하나의 state를 관리하면 하나의 데이터 조각의 변경에 다른 데이터도 전부 영향이 받는다는게 문제. 그래서 이걸 각각 쪼개는등의 패턴을 쓰거나 하는 방식으로 하는것. 예를들어서 Provider를 상태 의미단위로 쪼개서 각각 상태를 관리하면 되긴 함.
익명(211.209)2023-07-28 11:34
답글
보통 useSelector(Redux나), useContextSelector에서 하는 내용들은 Parent영역 <-> 해당 상태를 구독하는 컴포넌트 사이에 하나의 observer를 둬서 내가 '쓰는값' 이 변경되었을 때만 리랜더링 호출해주는 컨셉. 그러니까 내가 위에서 말한 https://github.com/facebook/react/pull/20646 요런애들은 Context의 props변경으로 인한 리랜더링 호출로 막는 케이스가 아니라, Context state에서 내가 쓰는 데이터가 아닌데 다른애가 써서 변경되어 나까지 리랜더링 되는것을 막는 케이스.
익명(211.209)2023-07-28 11:39
답글
3번에서 props 바뀌면 리렌더링 되는것도 사실 대부분의 경우 부모에서 props 로 부모상태를 넣는데 부모상태가 바뀌면서 부모가 리렌더링돼서 자식이 리렌더링 되는 경우인듯. 2번이랑 같은 맥락. 컨텍스트의 단점은 4번 말대로이고 컨텍스트 쪼개면서 많아지기 때문에 컨텍스트관리가 어려워지는점. 글 본문처럼 useContext 사용 안 하는 곳까지 리렌더링 되는건 대부분 잘못 짠 경우
익명(223.62)2023-07-28 12:40
답글
(223.62) // 근데 내가 말한 흐름이 맞다면, useContext 사용 안 하는 곳까지 리렌더링 되는건 애초에 일어날 수 없는 상황 아닐까? 그러니까 여기선 '잘' 짠다라는 패턴과는 상관 없는 것 같은데.
애초에 컴포넌트끼리의 리랜더링은 말했듯이 Context API는 관련없는내용이고 props, state와 관련있는내용인데.. 저기서 말한 '잘' 못짠 상황이라는건 마치 Context API를 잘못짜게되면 Context API가 자식 컴포넌트 자체의 랜더링을 부추길 수 있다 라는 소리처럼 들려서 물어봄.
익명(211.209)2023-07-28 13:08
답글
예를들어 "App에서 Context.Prover 쓰고 App에 state 박아두는 케이스가 대부분이었음. 분리해서 children 을 props 로 받으면 Provider 내부의 state 가 변해도 children 은 props 라서 리렌더링 되지 않음."
이 케이스에서도 사실상 부모 props를 그대로 받지 않는 이상, 자식한테는 랜더링 영향이 없는게 맞는 것 같아서 그럼. (children으로 받던 그냥 직접 내부에 작성하던..)
익명(211.209)2023-07-28 13:12
답글
난 잘 짜는게 뭔지에 대해서 얘기한적은 없고 잘못짜놓고 안좋다고 하는 사람들이 많다는 걸 얘기한거 뿐임. 또 애초에 잘못 알고 있는 경우도 많고.
익명(223.62)2023-07-28 13:13
답글
님이 첨부한 코드 예시가지고도 확인해봄.
이 상황 한정해서는 부모와 자식간의 리랜더링 관계는 props만 없애면 끊어지는거고
context에서 내려준 state관리는 context 내부의 state 관리문제인거지, context 자체의 문제와는 거리가 있다라는 의미로 생각 중.
익명(211.209)2023-07-28 13:15
답글
무슨 얘기인지 이해가 안가는데 App 에 state 만들고 Context.Provider 를 App에서 value에 배열 넣어도 Test2만 리렌더링 된다는거임?
익명(223.62)2023-07-28 13:20
답글
아 이거 내가 테스트를 잘못했다. 님 말이 맞음.
생각해 보니 뭔가 모순이 있어서 다시 체크해보았는데 내가 테스트를 잘못했네.
다시 확인해줘서 감사요.
익명(211.209)2023-07-28 13:26
리엑트는 잘 모르겠지만 아무튼 오개념 많은 이유가 바로 그거임 쓰지 말자는 글들이 어그로가 잘 끌림 딱 봐도 써본지 일주일된 애가 어렵다고 징징 거리는 소린데 초고수가 언어론적 분석하는거처럼 취급해줌 ㅋ
그래서 context api 잘짜는게 뭔데ㅋㅋ
잘 짠건 몰라도 사용자 문제인게 대다수. provider value 에 객체 그냥 박아넣는 것도 보고 value 바뀌면 provider 자식이 다 리렌더링된다고 주장하는 글도 있더라
다 바뀌는거아님? 적어도 랜더링 시도는 할거아녀.
정확히말하면 Context Provider 자체의 props가 변경이 되는것을 리액트가 감지하면 룰에 의해서 아래 있는 자식들도 다 랜더링 시도하는거 아닌가 했음. React.memo로 감싸져있거나, 변경 영향 없으면 당연히 그 아래부터는 랜더링 시도 안할거고.
그리고 provider에 value를 그대로 안박는 케이스가 있음..? 그것도 궁금하네. 그냥 mutable한 object 껴넣고 처리하는건가?
객체 박아넣고 reducer + dispatch로 처리하는거지뭔
렌더링이랑 컨텍스트 관련한 오개념 ㄹㅇ 많음
이거 보고 이상해서 직접 react-dev-tools로 실험해봤는데 리랜더링 됨. react.memo를 쓰면 자식들 랜더링 phase를 패스하는것도 확인 함. props가 변경되면 당연히 리랜더링 고쳐지는게 react 랜더링의 원칙인데 왜 이게 틀린가 했음. 혹시 리랜더링을 dom에 새롭게 그리는 과정으로 오해한게 아닌지..
물론 context api를 그거 때문에 쓰지 않는다는건 좀 비약이 심하지만 (다른 이유가 더 크지만) 리액트가 워낙 랜더링 체크 퍼포먼스가 저조할 수 밖에 없는 환경이라, 이런거 챙겨주는것만해도 스크립트 로딩속도나 스크립트 처리속도 향상되는것도 맞을듯
Provider 자식 전체가 아니라 useContext 사용한 곳에서만 렌더링 돼야 정상임. 코드 한 번 올리면 볼게. 블로그 글의 대부분의 경우 Provider 분리 안 하고 바로 App에서 Context.Prover 쓰고 App에 state 박아두는 케이스가 대부분이었음. 분리해서 children 을 props 로 받으면 Provider 내부의 state 가 변해도 children 은 props 라서 리렌더링 되지 않음.
value에 객체 그대로 박는다는 얘기는 구체적으로 말하면 Context 를 루트에서 사용하지 케이스에서 부모가 리렌더링 되는 경우에 useMemo를 써야한다는 얘기였고
1) 분리해서 children 을 props 로 받으면 Provider 내부의 state 가 변해도 children 은 props 라서 리렌더링 되지 않음. =>일단 이렇게 쓰게되면 value에 그냥 객체를 받는다고 가정할게. 그럼 Provider의 value={} props가 변하니까 children은 영향을 받게 되는 셈임. App이랑은 상관없음.
React.memo : This memoized version of your component will usually not be re-rendered when its parent component is re-rendered as long as its props have not changed. => 다른말로 parent 의 props가 변경되면 child의 re-render가 불린다. 그러니 React.memo, shouldComponentUpdate 이런거 썼고.
2) value에 객체 그대로 박는다는 얘기는 구체적으로 말하면 Context 를 루트에서 사용하지 케이스에서 부모가 리렌더링 되는 경우에 useMemo를 써야한다는 얘기였고 요 내용은 context 쓸 때 useMemo, useCallback 같은거 껴넣어서 최대한 props가 쓸데없이 변경되지 말자라는 의미 같은데 (특히 callback류 함수들은 이런 리랜더링에 매번 새로운 함수를 생성하니까). 그거랑 "useContext 사용한 곳에서만 렌더링 돼야 정상임" 이것과는 상관없다는것같음.
그럴거면
https://github.com/facebook/react/pull/20646
요런 이야기나
https://github.com/facebook/react/issues/21329
요런 이야기는 왜나올까 싶음.
내가 짠건데 확인해봐
https://codesandbox.io/s/practical-hellman-r3lh84?file=/src/App.js
예제 감사. 예제보고 내가 예상했던것과 동작이 달라서 내가 잘못 이해한 부분이 있는 것 같아 정리해봤음. 일깨워줘서 감사. (위에 댓글 보고 오해하시는 분들 있을 것 같아서 정리) 1. React-dev-tools는 랜더링 시점 제대로 캐치 못하는듯. Profile쓰거나 아니면 컴포넌트 함수 내부에서 직접 호출하면 될 듯. (dev-tools는 위 예제도 리랜더링 되었다고 뜸) 2. Context 자체는 리랜더링과 관련이 없음. 이 부분이 내가 틀리게 알고 있던 부분인데 Context를 쓰는 패턴이 리랜더링을 부를 수 있는 거고, Context 자체는 리랜더링과 상관없음.
3. 리랜더링 여부는 props와 state와 관련있음 만약 특정 컴포넌트가 state나 props가 변경되면 그 하위의 컴포넌트들이 리랜더링 후보가 됨. 위 예제에서는 각 컴포넌트가 애초에 props가 없으니 리랜더링 과는 관련이 없음. 4. Context가 리랜더링에 취약하다는건, 하나의 useState에 모든 데이터를 모는 경우, 혹은 하나의 useReducer로 모든 데이터를 하나의 state를 관리하면 하나의 데이터 조각의 변경에 다른 데이터도 전부 영향이 받는다는게 문제. 그래서 이걸 각각 쪼개는등의 패턴을 쓰거나 하는 방식으로 하는것. 예를들어서 Provider를 상태 의미단위로 쪼개서 각각 상태를 관리하면 되긴 함.
보통 useSelector(Redux나), useContextSelector에서 하는 내용들은 Parent영역 <-> 해당 상태를 구독하는 컴포넌트 사이에 하나의 observer를 둬서 내가 '쓰는값' 이 변경되었을 때만 리랜더링 호출해주는 컨셉.
그러니까 내가 위에서 말한
https://github.com/facebook/react/pull/20646
요런애들은 Context의 props변경으로 인한 리랜더링 호출로 막는 케이스가 아니라,
Context state에서 내가 쓰는 데이터가 아닌데 다른애가 써서 변경되어 나까지 리랜더링 되는것을 막는 케이스.
3번에서 props 바뀌면 리렌더링 되는것도 사실 대부분의 경우 부모에서 props 로 부모상태를 넣는데 부모상태가 바뀌면서 부모가 리렌더링돼서 자식이 리렌더링 되는 경우인듯. 2번이랑 같은 맥락. 컨텍스트의 단점은 4번 말대로이고 컨텍스트 쪼개면서 많아지기 때문에 컨텍스트관리가 어려워지는점. 글 본문처럼 useContext 사용 안 하는 곳까지 리렌더링 되는건 대부분 잘못 짠 경우
(223.62) // 근데 내가 말한 흐름이 맞다면, useContext 사용 안 하는 곳까지 리렌더링 되는건 애초에 일어날 수 없는 상황 아닐까? 그러니까 여기선 '잘' 짠다라는 패턴과는 상관 없는 것 같은데. 애초에 컴포넌트끼리의 리랜더링은 말했듯이 Context API는 관련없는내용이고 props, state와 관련있는내용인데.. 저기서 말한 '잘' 못짠 상황이라는건 마치 Context API를 잘못짜게되면 Context API가 자식 컴포넌트 자체의 랜더링을 부추길 수 있다 라는 소리처럼 들려서 물어봄.
예를들어 "App에서 Context.Prover 쓰고 App에 state 박아두는 케이스가 대부분이었음. 분리해서 children 을 props 로 받으면 Provider 내부의 state 가 변해도 children 은 props 라서 리렌더링 되지 않음." 이 케이스에서도 사실상 부모 props를 그대로 받지 않는 이상, 자식한테는 랜더링 영향이 없는게 맞는 것 같아서 그럼. (children으로 받던 그냥 직접 내부에 작성하던..)
난 잘 짜는게 뭔지에 대해서 얘기한적은 없고 잘못짜놓고 안좋다고 하는 사람들이 많다는 걸 얘기한거 뿐임. 또 애초에 잘못 알고 있는 경우도 많고.
님이 첨부한 코드 예시가지고도 확인해봄. 이 상황 한정해서는 부모와 자식간의 리랜더링 관계는 props만 없애면 끊어지는거고 context에서 내려준 state관리는 context 내부의 state 관리문제인거지, context 자체의 문제와는 거리가 있다라는 의미로 생각 중.
무슨 얘기인지 이해가 안가는데 App 에 state 만들고 Context.Provider 를 App에서 value에 배열 넣어도 Test2만 리렌더링 된다는거임?
아 이거 내가 테스트를 잘못했다. 님 말이 맞음. 생각해 보니 뭔가 모순이 있어서 다시 체크해보았는데 내가 테스트를 잘못했네. 다시 확인해줘서 감사요.
리엑트는 잘 모르겠지만 아무튼 오개념 많은 이유가 바로 그거임 쓰지 말자는 글들이 어그로가 잘 끌림 딱 봐도 써본지 일주일된 애가 어렵다고 징징 거리는 소린데 초고수가 언어론적 분석하는거처럼 취급해줌 ㅋ