Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs React中组件之间共享功能的正确方法_Reactjs - Fatal编程技术网

Reactjs React中组件之间共享功能的正确方法

Reactjs React中组件之间共享功能的正确方法,reactjs,Reactjs,我有多个组件都需要做同样的事情。(一个简单的函数,映射到它们的子组件上,并对每个子组件执行某些操作)。目前,我正在每个组件中定义此方法。但我只想定义它一次 我可以在顶级组件中定义它,然后将其作为道具传递下去。但这感觉不太对。与其说它是道具,不如说它是一个库函数。(在我看来) 正确的方法是什么?如果您使用类似的工具,那么您可以拥有一个外部文件,即util.js,用于导出一些实用程序函数 var doSomething = function(num) { return num + 1; } ex

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

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

正确的方法是什么?

如果您使用类似的工具,那么您可以拥有一个外部文件,即util.js,用于导出一些实用程序函数

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

exports.doSomething = doSomething;
然后根据需要要求它

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

听起来像是一个实用功能,那么为什么不把它放在一个单独的静态实用模块中呢

否则,如果使用像Babel这样的transpiler,您可以使用es7的静态方法:

class MyComponent extends React.Component {
  static someMethod() { ...
或者,如果您使用的是React.createClass,则可以使用以下对象:

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

此外,您不应该将一个方法作为道具传递给所有组件,因为它会将它们紧密耦合,使重构更加痛苦。我建议使用普通的旧实用模块


另一种选择是使用mixin来扩展类,但我不建议这样做,因为在es6+中不能这样做(在这种情况下我看不到好处)。

您不应该使用mixin吗?看

尽管他们不受欢迎,你看


可能有用

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

解决方案1:使用CommonJS模块语法 解决方案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({});
资料来源:

组件(重用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;
从“/Categories.jsx”导入类别;
从“../utils/FetchUtil”导入FetchUtil;
从“物料界面/网格”导入网格;
从“React”导入React;
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
this.state={categories:[]};
}
组件willmount(){
窗口
.fetch(“/rest/service/v1/categories”)
.then(FetchUtil.handleError)
.then(response=>response.json())
.then(categories=>this.setState({…this.state,categories}));
}
render(){
返回(
);
}
}
导出默认应用程序;

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


这被认为是React中的一个良好实践

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

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

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

<SomeOtherItem
    ref={(instance) => {this.childB = instance}}
/>
export const getTimeDifference = function (start, end) {
    // return difference between start and end
}
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"));
    }
}
样式2-可以在
/utils/time.js
中这样创建Util类型的组件

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

<SomeOtherItem
    ref={(instance) => {this.childB = instance}}
/>
export const getTimeDifference = function (start, end) {
    // return difference between start and end
}
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"));
    }
}
然后可以像这样在
/components/App.js
中使用它们

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

<SomeOtherItem
    ref={(instance) => {this.childB = instance}}
/>
export const getTimeDifference = function (start, end) {
    // return difference between start and end
}
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"));
    }
}
使用哪个?

如果逻辑相对相关(它们只在同一个应用程序中一起使用),那么您应该在组件之间共享状态。但是,如果您的逻辑是远亲的(即math-util、text-formatting-util),那么您应该创建并导入util类函数。

Utils.js使用最新的Javascript ES6语法
var doSomething = function(num) {
 return num + 1;
}

exports.doSomething = doSomething;
像这样创建具有多个函数的
Utils.js
文件,等等

const someCommonValues=['common','values'];
导出常量doSomethingWithInput=(输入)=>{
//对输入做些什么
返回输入;
};
导出常量justAnAlert=()=>{
警惕(“你好”);
};
然后在要使用util函数的组件中,导入所需的特定函数。您不必导入所有内容

从“/path/to/utils.js/file”导入{doSomethingWithInput,justAnAlert}
然后在组件中使用这些函数,如下所示:

justAnAlert();
{doSomethingWithInput('hello')}


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

  • 创建Helpers.js文件:

    导出函数myFunc(){
    返回this.state.name;//根据需要定义它
    }

  • 在组件文件中导入帮助器函数:

    从'path to/Helpers.js'导入{myFunc}

  • 在构造函数中,将该助手函数添加到类中

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

  • 在渲染函数中使用它:

    render(){
    {this.myFunc()}
    }


  • 关于mixin的信息很有用。在这种情况下,我希望有条件地使用该函数,而不是让某个生命周期事件自动发生。所以正如您所说的,一个简单的旧实用程序函数是一个不错的选择。注意:
    React.createClass
    自React 15.5.0以来就被弃用了。create react应用程序建议使用npm模块
    创建react类
    。我希望做与OP相同的事情,但我在这里有点困惑。您不推荐您列出的任何选项。你推荐什么?我会简单地为函数编写一个文件,例如“代码> DOSOMETHONE .JS<代码>,或者是一个具有多个类似的“实用程序”功能的文件,例如“代码> UTILS.JS,并导入那些需要使用的函数。我同意MIXIN是一个更好的解决方案,而不仅仅是导出一个公共函数。”1.