2015-11-06 27 views
5

Tôi không thể tìm ra cách truyền đạo cụ cho thành phần. Điều này quan trọng vì tôi không muốn tìm nạp dữ liệu trong phương thức componentDidMount vì nó sẽ không nhìn thấy được với các công cụ tìm kiếm.Với getComponent làm thế nào để vượt qua đạo cụ?

Mã của tôi trông như thế này

const router = 
<Route path="/" component={App}> 
<IndexRoute onEnter={redirectToLogin} component={LandingPage} /> 
<Route path="panel" component={ ControlPanel }> 
    ... 
</Route> 
<Route 
    path="/:handle" 
    onEnter={maybeRedirectToHome} 
    getComponent={(location, callback)=> { 
     getSiteHandleByName(location.pathname.slice(1)) 
     .then(function(handle){ 
     if (handle){ 
      callback(null, Portfolio) 
     } else { 
      callback(null, NotFound) 
     } 
     }) 
     .catch(callback) 
    }} 
    getChildRoutes={(location, callback)=> { 
    callback(null, portfolioRoutes) 
    }} 
/> 
</Route> 

Tôi đang cố gắng để phục vụ lập một danh mục đầu tư React App khi người dùng truy cập một địa chỉ hợp lệ như mysite.com/thishandleisvalid nhưng tôi sẽ cũng cần phải lấy tất cả các nội dung cho ứng dụng đó tại số getComponent và chuyển nó làm tài sản. Ví dụ. bạn có thể làm một cái gì đó như thế này <Portfolio contentItems={fetchedItems} />.

Làm điều này có thể không?

Trả lời

16

Điều này thực sự dễ thực hiện với các thành phần không trạng thái. Chỉ cần làm một cái gì đó như:

function getComponent(location, callback) { 
    const Component = /* ... */; 
    const items = /* ... */; 

    callback(null, props => <Component {...props} items={items} />); 
} 

Lý do chúng tôi không hỗ trợ một cách rõ ràng loại này của mô hình là vì nó khá điển hình để dây mọi thứ theo cách này - cho các ứng dụng mà cần phải đối phó với các loại điều này, đó là nhiều phổ biến hơn để sử dụng móc onEnter để ví dụ cư trú một cửa hàng Flux, sau đó kết nối các thành phần thích hợp với các cửa hàng có liên quan.

+0

Điều này thật tuyệt vời. Và cảm ơn bạn đã biết thông tin về việc sử dụng móc onEnter và một cửa hàng thông lượng. Đó vẫn là một khu vực tôi thấy khó hiểu và cần phải tìm hiểu. – Ally

+0

Điều này phù hợp với tôi vì tôi đang cố gắng chỉ chuyển các hành động đến một thành phần trên cơ sở mỗi tuyến mà không gây ô nhiễm đạo cụ trên ứng dụng, nói rằng nếu tôi sử dụng các hành động 'React.cloneElement (this.props.children, {' ': fooActions})' tại gốc ứng dụng. – mpoplin

5

Ngoài ra nếu bạn không nhớ truy cập vào đạo cụ dưới route, bạn có thể vượt qua đạo cụ như thế này:

JSX:

<Route 
    path="route_path" 
    customProp="hello" 
    getComponent={(location, cb) => { 
    // ... 
    }} 

Programatically:

childRoutes: [ 
{ 
    path: 'route_path', 
    customProps: 'hello', 
    getComponent(location, cb) { 
    // .... 
    }, 

customProp sẽ có sẵn qua props.route.customProp

+1

Có một số tài liệu về điều này? –

0

currying trông như là một cách đơn giản hơn (và thậm chí đơn giản hơn với recompose/withProps)

const getComponentWithProps = (props) => 
    (location, cb) => { 
    const Component = /* ... */; 
    // ... 
    cb(null, withProps(props)(Component)) 
    } 
... 
childRoutes: [ 
    { 
    path: 'route_path', 
    getComponent: getComponentWithProps({ foo: 'bar' }), 
    } 
] 

CẬP NHẬT

CHÚ Ý: CÁC phiên bản của tôi chỉ là một sugaring qua câu trả lời taion của, và, tôi cho rằng, có những rắc rối tương tự: nó gây ra hoàn thành thành phần rerender trên định tuyến lại.

điều đó xảy ra do thành phần được rewrapping với withProps enhancer trên mỗi vị trí mới, tạo thành phần mới trên mỗi định tuyến lại.

là giải pháp nhanh chóng, tôi đã quyết định cache tất cả các cải tiến trong bản đồ yếu. trong trường hợp của tôi, có vẻ như

const getOrAdd = (map) => 
    (value = Function.prototype) => 
    (key) => 
     map.get(key) 
     || (
      map.set(
      key, 
      value(), 
     ) 
      && map.get(key) 
     ); 

const componentsMap = new WeakMap(); 
export const getEnhancedMap = getOrAdd(componentsMap)(() => new WeakMap()); 

export const getEnhancedComponent = (
    component, 
    enhancer, 
) => { 
    const enhancedMap = getEnhancedMap(component); 
    return getOrAdd(enhancedMap)(() => enhancer(component))(enhancer); 
} 
Các vấn đề liên quan