React 中组件之间共享函数的正确方法

我有多个组件,都需要做同样的事情。(一个简单的函数,它映射到它们的子组件,并对每个子组件执行一些操作)。目前我正在每个组件中定义这个方法。但我只想定义一次。

我可以在顶层组件中定义它,然后将其作为道具传递下去。但感觉不太对劲。与其说它是一个道具,不如说它是一个库函数。(在我看来)。

做这件事的正确方法是什么?

111048 次浏览

如果您使用类似于 浏览的东西,那么您可以有一个外部文件,即 util.js,它导出一些实用程序函数。

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


exports.doSomething = doSomething;

那就按需要来

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

听起来像一个实用程序函数,在这种情况下,为什么不把它放在一个单独的静态实用程序模块?

否则,如果使用像 Babel 这样的传输器,你可以利用 es7的静态方法:

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

否则,如果使用 React.createClass,可以使用 statics对象:

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

然而,我并不建议使用这些选项,包含实用工具方法的组件是没有意义的。

此外,您不应该将一个方法作为支撑传递给所有组件,这样会使它们紧密耦合,使重构更加痛苦。我建议使用普通的老式公共设施模块。

The other option is to use a mixin to extend the class, but I don't recommend that as you can't do it in es6+ (and I don't see the benefit in this case).

Here are some examples on how you can reuse a function (FetchUtil.handleError) in a React component (App).

Solution 1: Using CommonJS module syntax

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

解决方案2: 使用“ createClass”(React 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;

注意: 如果您使用 React v15.4(或更低版本) ,您需要导入 createClass,如下所示:

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

资料来源: https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactcreateclass

组件(重用 FetchUtil)

组件/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;

Another solid option other than creating a util file would be to use a higher order component to create a withComponentMapper() wrapper. This component would take in a component as a parameter and return it back with the componentMapper() function passed down as a prop.

在 React. 你可浏览此网页了解详情。中,这被认为是一个很好的实践

下面我将展示两种样式,您将根据组件的逻辑相互关联的程度进行选择。

样式1-相对相关的组件 可以是 被创造出来和回调引用,像这样,在 ./components/App.js..。

<SomeItem
ref={(instance) => {this.childA = instance}}
/>


<SomeOtherItem
ref={(instance) => {this.childB = instance}}
/>

然后你可以像这样在它们之间共享 使用函数。

this.childA.investigateComponent(this.childB);  // call childA function with childB as arg
this.childB.makeNotesOnComponent(this.childA);  // call childB function with childA as arg

样式2-Util-type 组件 可以是这样的 被创造出来,在 ./utils/time.js..。

export const getTimeDifference = function (start, end) {
// return difference between start and end
}

然后它们可以是 用过像这样,在 ./components/App.js..。

import React from 'react';
import {getTimeDifference} from './utils/time.js';


export default class App extends React.Component {
someFunction() {
console.log(getTimeDifference("19:00:00", "20:00:00"));
}
}

用哪个?

如果逻辑是 relatively-related(它们只在同一个应用程序中一起使用) ,那么您应该在组件之间共享状态。但是如果您的逻辑是 distantly-related(例如,数学 util,文本格式化 util) ,那么您应该创建并导入 util 类函数。

Js 和最新的 Javascript ES6语法

使用多个函数等创建这样的 Utils.js文件

const someCommonValues = ['common', 'values'];


export const doSomethingWithInput = (theInput) => {
//Do something with the input
return theInput;
};


export const justAnAlert = () => {
alert('hello');
};

然后在要使用 util 函数的组件中,导入所需的特定函数。你不用什么都进口

import {doSomethingWithInput, justAnAlert} from './path/to/utils.js/file'

然后像这样在组件中使用这些函数:

justAnAlert();
<p>{doSomethingWithInput('hello')}</p>

如果要操作 helper 函数中的状态,请遵循以下步骤:

  1. 创建一个 Helpers.js 文件:

    export function myFunc(){ 返回 this. state.name;//根据您的需要定义它 }

  2. 在组件文件中导入 helper 函数:

    import {myFunc} from 'path-to/Helpers.js'

  3. 在构造函数中,将助手函数添加到类中

    构造函数(){ This. myFunc = myFunc.bind (this) }

  4. 在渲染函数中使用:

    () < div > { this. myFunc ()}

}