React의 놀라운 렌더링 도구 모드.js — 저리 가!
What is the Render props pattern? The Render props pattern is a way for us to create a component that provides some kind of data to a child component.
우리 왜 이러는 거야?상상해 보자. 우리는 다음과 같은 몇 가지 일을 하고 싶다.
데이터를 가져올 때 HTTP의 혼란을 추상화하고 완성된 후에 데이터를 제공할 수 있는 구성 요소가 있다면 좋지 않습니까?
A/B 테스트는 응용 프로그램을 생산에 투입할 때 최종적으로 개선하고 싶지만, 최선의 방법을 모르거나, 코드를 자주 발표하고 생산으로 옮기고 싶을 수도 있지만, 일부 기능은 아직 준비가 되지 않았기 때문에, 어떤 것들이 보일지 여부를 조건부로 결정하기를 희망한다.
만약 당신이 상술한 어떤 상황이 있다면, 당신은 다시 사용할 수 있는 기능을 가지게 될 것이다.다시 사용할 수 있는 기능이 생기면 함수나 구성 요소로 추상화하고 싶을 수도 있고, 우리는 후자를 선택할 것이다.
만약 우리가 이 기능을 위해 구성 요소를 만들고 그것을 특정한 구성 요소에 제공할 수 있다면, 그것은 좋지 않습니까?이 하위 구성 요소는 데이터가 제공되고 있는지 알 수 없습니다.
어떤 의미에서, 이것은 우리가 공급자에게 한 일과 유사하지만, 용기 구성 요소 포장이 구성 요소를 나타내는 방식과도 유사하다.이것은 약간 흐릿하게 들리기 때문에 외관을 보여 드리겠습니다.
const ProductDetail = ({ product }) => (
<React.Fragment>
<h2>{product.title}</h2>
<div>{product.description}</div>
</React.Fragment> )
<Fetch url="some url where my data is"
render={(data) => <ProductDetail product={data.product} /> }
/>
위에서 보듯이 우리는 두 개의 다른 구성 요소ProductDetail
와 Fetch
가 있다.ProductDetail
프레젠테이션 구성 요소처럼 보입니다.Fetch
한편으로는 좀 달라 보인다.그 위에 하나의 속성 URL이 있는데, 보기에 그것은render 속성이 있고, 최종적으로 우리의 ProductDetail
를 나타낸다.렌더링 도구 설명
우리는 그것에 대해 역방향 공정을 진행하고 그 작업 원리를 찾아낼 수 있다.
코드를 다시 살펴보겠습니다.
<Fetch url="some url where my data is"
render={(data) => <ProductDetail product={data.product} /> }
/>
우리Fetch 구성 요소에는 속성render
이 있는데, 이 속성은 JSX를 최종적으로 생성하는 함수를 사용한 것 같습니다.문제는 전체renderprops 모드가 우리가 되돌아오는 방법에서 함수를 호출하는 것에 관한 것이다.몇 가지 코드를 보여 드리겠습니다.class Fetch extends React.Component {
render() {
return this.props.render();
}
}
이것이 가장 간단한 패턴이다.우리가 Fetch
구성 요소를 사용하는 방식은 최소한 this.props.render()
호출에 내용을 보내야 한다는 것을 의미한다.위의 함수 호출 위치만 추출하여 보십시오.(data) => <ProductDetail product={data.product} />
우리는 위에서 볼 수 있듯이, 우리는 매개 변수 데이터가 필요하다. 데이터는 마치 하나의 대상인 것 같다.네, 그럼 데이터는 어디에서 나오나요?이것이 바로 저희 Fetch
구성 요소입니다. 이것은 HTTP 호출을 실행하는 번거로운 작업을 수행해 줍니다.HTTP에 대한 어셈블리 생성하기
다음과 같이 라이프 사이클 방법을
Fetch
에 추가합니다.class Fetch extends React.Component {
state = {
data: void 0,
error: void 0
}
componentDidMount() {
this.fetchData();
}
async fetchData() {
try {
const response = await fetch(this.props.url);
const json = await response.json();
this.setState({ data: json });
catch (err) {
this.setState({ error: err })
}
}
render() {
if (!this.state.data) return null;
else return this.props.render(this.state.data);
}
}
Quick note, if you are unfamiliar with
void 0
, that’s just setting something toundefined
알겠습니다. 이제 우리는 우리의 구성 요소를 충실하게 했습니다.HTTP 호출을 하는 방법
fetchData()
을 추가했습니다. 이것은 주어진 방법this.props.url
입니다. 설정render()
이 없으면 저희this.state.data
방법은null을 보일 것입니다. 그러나 HTTP 호출이 완료되면 JSON 응답 호출this.props.render(data)
을 사용할 것입니다.그러나 세 가지가 부족합니다.
오류 처리, 오류 처리에 논리를 추가해야 합니다
로드를 처리할 때 OFFETCH () 호출이 완료되지 않았을 때, 우리는 지금 아무것도 보이지 않습니다. 이것은 좋지 않습니다.
이 일을 처리하다.도구.url, 이 도구는 처음에 설정하지 않을 수도 있고 시간의 추이에 따라 바뀔 수도 있기 때문에 이 문제를 처리해야 합니다
오류 처리
우리는
render()
방법의 catch 자구에서 설정 this.state.error
의 논리를 작성했기 때문에 this.state.error
방법에 적응하기 위해 fetchData()
방법을 약간 바꾸어서 이 문제를 쉽게 처리할 수 있다.다음은 다음과 같습니다.
class Fetch extends React.Component {
state = {
data: void 0,
error: void 0
}
componentDidMount() {
this.fetchData();
}
async fetchData() {
try {
const response = await fetch(this.props.url);
const json = await response.json();
this.setState({ data: json });
catch (err) {
this.setState({ error: err })
}
}
render() {
const { error, data, loading } = this.state;
if(error) return this.props.error(error);
if (data) return this.props.render(data);
else return null;
}
}
위에서 우리는 처리 방법을 첨가했다.주 정부.this.props.error()
를 호출하는 중 오류가 발생했습니다. 따라서 Fetch
구성 요소를 사용하려고 시도할 때 이 점을 반영해야 합니다.하역
이 경우 아래 그림과 같이 새 상태 로드를 추가하고 업데이트
render()
방법을 사용하여 이러한 속성을 확인할 수 있습니다.class Fetch extends React.Component {
state = {
data: void 0,
error: void 0,
loading: false
}
componentDidMount() {
this.fetchData();
}
async fetchData() {
try {
this.setState({ loading: true });
const response = await fetch(this.props.url);
const json = await response.json();
this.setState({ data: json });
this.setState({ loading: false });
catch (err) {
this.setState({ error: err })
}
}
render() {
const { error, data, loading } = this.state;
if(loading) return <div>Loading...</div>
if(error) return this.props.error(error);
if (data) return this.props.render(data);
else return null;
}
}
현재, 위에서 우리가 불러오는 것을 처리할 때 약간 흐리멍덩하다. 네, 우리는 그것을 위해 if
을 추가했지만, 우리가 과장한 내용은 마이크로스피커나 그림자 이미지처럼 보이는 좋은 구성 요소를 사용해서 개선할 수 있기 때문에 고려할 필요가 있습니다.변경 사항을 처리합니다.도구.사이트 주소
이것은 충분히 가능하다. 이 사이트의 주소는 바꿀 수 있다. 우리는 이런 구성 요소를 사용할 계획이 없으면 그것에 영합해야 한다.
이 경우 이 절을 건너뛰고 다음 절을 봐야 한다.)
React API가 최근에 변경되었습니다. 변경하기 전에 도구가 변경되었는지 확인하기 위해 라이프 사이클 방법
componentWillReceiveProps()
을 추가해야 합니다. 이것은 안전하지 않다고 여겨지기 때문에 사용해야 합니다.componentDidUpdate(prevProps) {
if (this.props.url && this.props.url !== prevProps.url){
this.fetchData(this.props.url);
}
}
이것이 바로 우리가 필요로 하는 것이다. 이 구성 요소의 전체 코드를 보여 주자.class Fetch extends React.Component {
state = {
data: void 0,
error: void 0,
loading: false
}
componentDidMount() {
this.fetchData();
}
componentDidUpdate(prevProps) {
if (this.props.url && this.props.url !== prevProps.url) {
this.fetchData(this.props.url);
}
}
async fetchData() {
try {
this.setState({ loading: true });
const response = await fetch(this.props.url);
const json = await response.json();
this.setState({ data: json });
this.setState({ loading: false });
catch (err) {
this.setState({ error: err })
}
}
render() {
const { error, data, loading } = this.state;
if(loading) return <div>Loading...</div>
if(error) return this.props.error(error);
if(data) return this.props.render(data);
else return null;
}
}
이제 구성 요소를 사용하려면 다음을 입력합니다.<Fetch
url={url-to-product}
render={(data) => <ProductDetail product={data.product} />}
error={(error) => <div>{error.message}</div>}
/>
A/B 테스트
다음 사례로 넘어가겠습니다.이 구성 요소를 사용하여 코드가 조건부로 표시되기를 원하는 두 가지 주요 이유가 조만간 있을 것입니다.
그것은 아직 준비가 되지 않았습니다. 우리는 자주 배치하고 싶습니다. 우리는 제품 소유자에게 새로운 기능을 보여주고 싶을 수도 있습니다. 그러면 피드백을 수집할 수 있습니다. 그래서 만약에 우리가 로고로 이 구성 요소의 내용의 표시를 제어할 수 있다면 너무 좋습니다
A/B 테스트, 만약에 우리가 우리의 전자상거래 응용 프로그램에서 어떤 새로운 결제 페이지에 들어가고 싶은지 모른다고 가정하면, 만약 우리가 사용자의 절반을 버전 1, 나머지 절반을 버전 2로 보낼 수 있다면 다행이다.이 경우, 두 개의 다른 페이지가 있을 수 있지만, 예를 들어 몇 개의 부분을 바꾸는 등 차이가 적으면, 이것은 좋은 후보자일 수 있습니다.
<FeatureFlag
flag={showAlternateSection}
render={()=> <div>Alternate design</div>}
else={()=> <div>Normal design</div>}
/>
위에는 구성 요소FeatureFlag
와 다음 속성이 있는데 이를 어떻게 사용하는지 자세히 분석해 보겠습니다.로고, 이것은 기능 로고의 이름으로 문자열일 가능성이 높다.
만약 기능 표지
그렇지 않으면, 만약 기능 표지가 비활성화되거나 존재하지 않는다면, 우리는 이 방법을 호출할 것이다
구성 요소 구축
좋습니다. 구성 요소를 어떻게 사용할 계획인지 알고 있습니다. 구성해 보겠습니다.
class FeatureFlag extends React.Component {
state = {
enabled: void 0
}
componentDidMount() {
const enabled = localStorage.getItem(this.props.flag) === 'true';
this.setState({ enabled });
}
render() {
if(enabled) return this.props.render();
else if(enabled === false) return this.props.else();
else return null;
}
}
네, 세 가지 상태를 소개하겠습니다.네, 국기가 진짜라는 걸 알았을 때
잘못, 우리가 국기가 틀렸다는 것을 알았을 때
void 0/정의되지 않았습니다. 이 때 로고 값이 해석되지 않았습니다.
그래, 좀 미친 듯이 들린다.
localStorage.getItem()
보통 반응이 빠르다.네, 그래요. 제가 좀 미쳤을 수도 있지만, 로고 값이
localStorage
에 없으나, 우리가 호출해야 할 서비스에 주재하고 있다면, 이 값을 회복하는 데 시간이 좀 걸릴 수도 있습니다.그래서 우리의
componentDidMount()
가 이렇다고 상상해 보세요.async componentDidMount() {
const enabled = await flagService.get(this.props.flag);
this.setState({ enabled });
}
서비스 태그를 localStorage
가 아닌 서비스 태그에 배치하려는 경우 다음과 같이 변경될 수 있습니다.요약
Render props 모드는 JSX 자체를 보여 주는 함수를 보여 줍니다. 보시다시피 이 디자인 모드를 바탕으로 매우 강력하고 유용한 구성 요소를 만들 수 있습니다.
당신이 이 문장이 유용하다고 생각하기를 바랍니다. 만약 당신이 유용하다고 생각한다면, 저에게 박수를 좀 주십시오.
읊다, 읊조리다
이것은 너의 잘못이 아니라 컴파일러의 잘못이라는 것을 명심해라.)
한층 더 읽다
Render props 패턴
Reference
이 문제에 관하여(React의 놀라운 렌더링 도구 모드.js — 저리 가!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/itnext/the-amazing-render-props-pattern-for-react-js-lifecycle-begone-433m텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)