在React中分享组件之间功能的正确方法

64 reactjs

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

我可以在顶级组件中定义它,然后将其作为道具传递下去.但这感觉不太对劲.它更像是一个库函数而不是一个prop.(在我看来).

这样做的正确方法是什么?

deo*_*owk 27

如果你使用类似browserify那么你可以有一个外部文件即是util.js中一些出口实用功能.

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

exports.doSomething = doSomething;
Run Code Online (Sandbox Code Playgroud)

然后根据需要要求它

var doSomething = require('./util.js').doSomething;
Run Code Online (Sandbox Code Playgroud)

  • 如果这些函数操纵状态应该怎么做? (28认同)

Fan*_*ing 16

具有最新Javascript ES6语法的Utils.js

Utils.js像这样使用多个功能创建文件

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

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

export const justAnAlert = () => {
   alert('hello');
};
Run Code Online (Sandbox Code Playgroud)

然后,在要使用util函数的组件中,导入所需的特定函数。您不必导入所有内容

import {doSomethingWithInput, justAnAlert} from './path/to/utils.js/file'
Run Code Online (Sandbox Code Playgroud)

然后在组件中使用这些功能,如下所示:

justAnAlert();
<p>{doSomethingWithInput('hello')}</p>
Run Code Online (Sandbox Code Playgroud)

  • 导入行末尾的“/file”是做什么用的? (2认同)
  • 最好将其保存在“/src”文件夹还是“/components”文件夹中? (2认同)
  • @Embedded_Mugs我会把它放在`src/helpers/utils.js`中。另外,我通常为类似的功能创建单独的文件,例如“pathHelpers”、“authHelpers” (2认同)

Ben*_*uer 7

以下是有关如何FetchUtil.handleError在React组件(App)中重用函数()的一些示例.

解决方案1:使用CommonJS模块语法

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

解决方案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;
Run Code Online (Sandbox Code Playgroud)

注意:如果您使用的是React v15.4(或更低版本),则需要createClass按如下方式导入:

import React from 'react';
const FetchUtil = React.createClass({});
Run Code Online (Sandbox Code Playgroud)

资料来源: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;
Run Code Online (Sandbox Code Playgroud)


Jak*_*ake 7

除了创建util文件之外的另一个可靠选项是使用更高阶的组件来创建withComponentMapper()包装器.该组件将接受一个组件作为参数,并将该componentMapper()函数作为prop传递回来.

这被认为是React的一个好习惯.您可以在此处详细了解如何执行此操作.


小智 6

如果要在辅助函数中操作状态,请遵循以下步骤:

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

    export function myFunc(){ return this.state.name; //define it according to your needs }

  2. 在您的组件文件中导入助手功能:

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

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

    constructor(){ this.myFunc = myFunc.bind(this) }

  4. 在渲染函数中使用它:

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


Hol*_*ger 5

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

样式 1 -可以使用回调引用创建相对相关的组件,像这样,在./components/App.js...

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

<SomeOtherItem
    ref={(instance) => {this.childB = instance}}
/>
Run Code Online (Sandbox Code Playgroud)

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

this.childA.investigateComponent(this.childB);  // call childA function with childB as arg
this.childB.makeNotesOnComponent(this.childA);  // call childB function with childA as arg
Run Code Online (Sandbox Code Playgroud)

样式 2 - Util 类型的组件可以这样创建,在./utils/time.js...

export const getTimeDifference = function (start, end) {
    // return difference between start and end
}
Run Code Online (Sandbox Code Playgroud)

然后他们可以使用这样的,在./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"));
    }
}
Run Code Online (Sandbox Code Playgroud)

使用哪个?

如果逻辑是相对相关的(它们只在同一个应用程序中一起使用),那么你应该在组件之间共享状态。但是,如果您的逻辑是远相关的(即数学工具、文本格式工具),那么您应该制作和导入 util 类函数。