2017-10-31 11 views
2

React App을 업그레이드하는 중입니다. 포장 된 구성 요소를 React Router (V4 등)에 전달하는 데 많은 시간이 걸린 후, 구성 요소는 새로운 소품이 전달 될 때마다 "마운트"됩니다.포장 된 구성 요소를 React Router에 지속적으로 다시 장착하지 않고 전달하는 방법

여기

은, 랩 된 구성 요소의 ...

export default function preload(WrappedComponent, props) { 
    class Preload extends React.Component { 
     componentWillMount() { 
      getDataForComponent(props); 
     } 

     render() { 
      return <WrappedComponent {...props} />; 
     } 
    } 
    return Preload; 
} 

그리고 여기에 우리가 그것을 사용하는 방법을 ...

const FlagsApp = (props) => { 
    return (
     <Route path="/report/:reportId/flag/:id/edit" component{preload(FlagForm, props)} /> 
    ); 
}; 

조치를 파견하고 업데이트를받을 때마다 구성 요소가 다시 탑재되어 많은 문제가 발생합니다. 새 구성 요소 클래스를

  • 당신이 Route.component 각각에 새로운 기능을 통과 할 때마다 만들 것이다 렌더링 동안 withRouter (..)를 호출

    • : 경우 GitHub의에 this thread에 따르면, 구성 요소를 다시 마운트합니다 예를 들어, 렌더링하다 내가 직접 문제가 해결의 FlagForm 구성 요소를 통과하면 새 구성 요소뿐만 아니라

    을 만들 것입니다 익명 함수 {...}을 (를)} /> 사용하지만, 그때는 이용할 수 없습니다 preload 함수 중 하나입니다.

    그렇다면 구성 요소를 다시 탑재하지 않고 어떻게 동일한 결과를 얻을 수 있습니까?

    미리 도움을 청하십시오!

  • +0

    프리로드가 어떻게 작동하는지 조금 설명해 주시겠습니까? 그것이받은 첫 번째 소품만으로 한 번만 데이터를 불러야합니까? 아니면 소품 변경에도 반응해야합니까? 예하에 필요한 소품은 어디에서 왔습니까? –

    답변

    1

    Route이 모든 업데이트에 새로운 구성 요소를 탑재하는 이유는 매번 preload을 통해 새 클래스가 할당 되었기 때문입니다.

    console.log(preload(FlagForm,props) != preload(FlagForm,props)) // true 
    

    그래서 문제가 preload가 내에서 호출되는 것입니다 이후 : 같은 인수로 호출 할 때

    사실, preload 호출 할 때마다 항상 별개의익명 클래스, 심지어 를 반환 FlagsApp 구성 요소의 render 메서드는 해당 범위를 벗어나 이동하여 시작하십시오.

    const PreloadedFlagForm = preload(FlagForm, props) //moved out 
    
    const FlagsApp = (props) => { 
        return (
         <Route path="/report/:reportId/flag/:id/edit" 
          component={PreloadedFlagForm} /> //assign component directly 
        ); 
    }; 
    

    이렇게하면 Route의 구성 요소는 업데이트간에 변경되지 않습니다.

    이제는 약 props에 대한 인수가 preload인데, 이것은 실제로 반 패턴입니다.

    const PreloadedFlagForm = preload(FlagForm) //drop the props arg 
    
    const FlagsApp = (props) => { 
        return (
         <Route path="/report/:reportId/flag/:id/edit" 
          component={<PreloadedFlagForm {...props} />} //spread it in here instead 
         /> 
        ); 
    }; 
    

    을 그리고 preload의 코드가된다 : 적절한 방법은 구성 요소에 대한 props 단지 표준 방법은 것에 전달하는

    export default function preload(WrappedComponent) { 
        class Preload extends React.Component { 
         componentWillMount() { 
          getDataForComponent(this.props); 
         } 
    
         render() { 
          return <WrappedComponent {...this.props} />; 
         } 
        } 
        return Preload; 
    } 
    

    희망이 도움이!당신이 지침을 읽어 보지 않았 나 같은 경우

    0

    는 대답은 <Route> 구성 요소의 render 소품에있다

    https://reacttraining.com/react-router/web/api/Route/render-func

    렌더링 :

    이 편리 허용 FUNC 위에서 설명한 원하지 않는 다시 마운트없이 인라인 렌더링 및 줄 바꿈을 수행 할 수 있습니다.

    그래서 대신 component 소품으로 래퍼 함수를 ​​전달하는, 당신은 render 소품을 사용해야합니다. 그러나, 위와 같이 포장 된 구성 요소는 전달할 수 없습니다. 나는 아직도 무슨 일이 벌어지고 있는지 완전히 이해하지 못한다. 그러나 params가 올바르게 전달되도록하기 위해서는 이것이 나의 해결책이었다. 내가 그렇게처럼 사용

    내 사전로드 래퍼 함수는 이제 경로를 렌더링 컴포넌트 반응한다

    ...

    export default class PreloadRoute extends React.Component { 
    
        static propTypes = { 
         preload: PropTypes.func.isRequired, 
         data: PropTypes.shape().isRequired, 
         location: PropTypes.shape({ 
          pathname: PropTypes.string.isRequired, 
         }), 
        } 
    
        componentWillMount() { 
         this.props.preload(this.props.data); 
        } 
    
        componentWillReceiveProps({ location = {}, preload, data }) { 
         const { location: prevLocation = {} } = this.props; 
    
         if (prevLocation.pathname !== location.pathname) { 
          preload(data); 
         } 
        } 
    
        render() { 
         return (
          <Route {...this.props} /> 
         ); 
        } 
    } 
    

    그리고 ...

    const FlagsApp = (props) => { 
        return (
         <Switch> 
          <PreloadRoute exact path="/report/:reportId/flag/new" preload={showNewFlagForm} data={props} render={() => <FlagForm />} /> 
          <PreloadRoute exact path="/report/:reportId/flag/:id" preload={showFlag} data={props} render={() => <ViewFlag />} /> 
          <PreloadRoute path="/report/:reportId/flag/:id/edit" preload={showEditFlagForm} data={props} render={() => <FlagForm />} /> 
         </Switch> 
        ); 
    }; 
    

    내가 전화 한 이유 this.props.preload 모두 componentWillMountcomponentWillReceiveProps인데, 그 이유는 탐색 할 때 다시 장착하지 않는 PreloadRoute 구성 요소의 반대 문제가 있었기 때문입니다.

    많은 사람들이 시간을 많이 낭비하지 않기를 바랍니다. 문자 그대로 일하는 것이 제대로 된 것 같습니다. 그게 우스운 출혈의 비용입니다!