2015-10-01 19 views
25

Tôi có nhiều thành phần cần phải thực hiện tương tự. (Một chức năng đơn giản mà bản đồ trên các thành phần con của họ và làm một cái gì đó cho mỗi một). Tại thời điểm này tôi đang xác định phương pháp này trong mỗi thành phần. Nhưng tôi chỉ muốn xác định nó một lần.Cách chính xác để chia sẻ các chức năng giữa các thành phần trong React

Tôi có thể xác định nó trong thành phần cấp cao nhất và sau đó chuyển nó xuống dưới dạng giá đỡ. Nhưng điều đó không hoàn toàn đúng. Nó là một chức năng thư viện hơn là một prop. (Dường như với tôi).

Cách chính xác để thực hiện việc này là gì?

Trả lời

11

Nếu bạn sử dụng một cái gì đó như browserify thì bạn có thể có tệp bên ngoài, ví dụ: util.js xuất một số hàm tiện ích.

var doSomething = function(num) { 
return num + 1; 
} 

exports.doSomething = doSomething; 

Sau đó yêu cầu nó khi cần thiết

var doSomething = require('./util.js').doSomething; 
+8

Điều gì nên được thực hiện nếu các chức năng này thao tác nhà nước? – aks

+0

@AnkitSinghaniya Điều đó phụ thuộc, bạn đang sử dụng gì để quản lý trạng thái kết thúc trước của ứng dụng? – deowk

+1

Tôi đang sử dụng các trạng thái phản ứng. – aks

3

Âm thanh như một chức năng hữu ích, trong trường hợp đó tại sao không đặt nó trong một mô-đun tiện ích riêng biệt tĩnh?

Nếu không nếu sử dụng một transpiler như Babel bạn có thể tận dụng các phương pháp tĩnh ES7 của:

class MyComponent extends React.Component { 
    static someMethod() { ... 

Hoặc khác nếu bạn đang sử dụng React.createClass bạn có thể sử dụng đối tượng statics:

var MyComponent = React.createClass({ 
    statics: { 
    customMethod: function(foo) { 
     return foo === 'bar'; 
    } 
    } 

Tuy nhiên, tôi không khuyên các tùy chọn đó, nó không có ý nghĩa để bao gồm một thành phần cho một phương thức tiện ích.

Ngoài ra, bạn không nên vượt qua một phương pháp xuống qua tất cả các thành phần của bạn như là một prop nó sẽ chặt chẽ cặp vợ chồng chúng và làm cho tái cấu trúc đau đớn hơn. Tôi khuyên một mô-đun tiện ích cũ đơn giản.

Tùy chọn khác là sử dụng mixin để mở rộng lớp, nhưng tôi không khuyên bạn nên không thể làm điều đó trong es6 + (và tôi không thấy lợi ích trong trường hợp này).

+0

Thông tin về mixin rất hữu ích. Trong trường hợp này, tôi muốn sử dụng chức năng này thay vì có điều kiện tự động xảy ra trên một sự kiện vòng đời. Vì thế. Như bạn nói một chức năng tiện ích cũ là cách để đi. –

+0

Lưu ý: '' React.createClass'' không được dùng nữa kể từ React 15.5.0. create-react-app đề nghị sử dụng module npm '' create-react-class'' để thay thế. –

2

Bạn không nên sử dụng Mixin cho điều này? Xem https://facebook.github.io/react/docs/reusable-components.html

Mặc dù họ đang rơi ra khỏi lợi thấy https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750

Có thể hữu ích

+0

Tôi đồng ý rằng mixin là một giải pháp tốt hơn ở đây hơn là chỉ xuất một chức năng chung. –

+0

@TaoHuang Một số điều cần xem xét, 1.Mixins không phải là bằng chứng trong tương lai và sẽ được sử dụng ngày càng ít trong các ứng dụng hiện đại, 2.Sử dụng một chức năng xuất khẩu làm cho khuôn khổ mã của bạn bất khả tri - bạn có thể dễ dàng sử dụng những chức năng trên bất kỳ dự án js khác. Ngoài ra, vui lòng đọc bài đăng này về lý do KHÔNG sử dụng Mixins -> https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html – deowk

+0

Mixin có thể truy cập và sửa đổi trạng thái, trong khi một đặc điểm không, và kể từ khi OP nói rằng họ muốn một cái gì đó để điều trị như một thư viện chức năng, một mixin sẽ không phải là giải pháp đúng. – HoldOffHunger

1

Dưới đây là một số ví dụ về cách bạn có thể tái sử dụng một chức năng (FetchUtil.handleError) trong một thành phần Phản ứng (App).

Giải pháp 1: Sử dụng CommonJS cú pháp mô-đun

module.exports = { 
    handleError: function(response) { 
    if (!response.ok) throw new Error(response.statusText); 
    return response; 
    }, 
}; 

Giải pháp 2: Sử dụng "createClass" (Phản ứng v16)

util/FetchUtil.js

const createReactClass = require('create-react-class'); 

const FetchUtil = createReactClass({ 
    statics: { 
    handleError: function(response) { 
     if (!response.ok) throw new Error(response.statusText); 
     return response; 
    }, 
    }, 
    render() { 
    }, 
}); 

export default FetchUtil; 

Lưu ý: Nếu bạn đang sử dụng React v15.4 (hoặc thấp hơn), bạn cần phải nhập khẩu createClass như sau:

import React from 'react'; 
const FetchUtil = React.createClass({}); 

Nguồn: https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactcreateclass

Component (mà reuses FetchUtil)

components/App.jsx

import Categories from './Categories.jsx'; 
import FetchUtil from '../utils/FetchUtil'; 
import Grid from 'material-ui/Grid'; 
import React from 'react'; 

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {categories: []}; 
    } 

    componentWillMount() { 
    window 
     .fetch('/rest/service/v1/categories') 
     .then(FetchUtil.handleError) 
     .then(response => response.json()) 
     .then(categories => this.setState({...this.state, categories})); 
    } 

    render() { 
    return (
     <Grid container={true} spacing={16}> 
     <Grid item={true} xs={12}> 
      <Categories categories={this.state.categories} /> 
     </Grid> 
     </Grid> 
    ); 
    } 
} 

export default App; 
Các vấn đề liên quan