Tengo varios componentes que deben hacer lo mismo. (Una función simple que mapea sus componentes secundarios y hace algo con cada uno). De momento estoy definiendo este método en cada uno de los componentes. Pero solo quiero definirlo una vez.
Podría definirlo en el componente de nivel superior y luego pasarlo como un accesorio. Pero eso no se siente del todo bien. Es más una función de biblioteca que un accesorio. (Me parece).
¿Cuál es la forma correcta de hacer esto?
Respuestas:
Si usa algo como browserify , puede tener un archivo externo, es decir, util.js que exporta algunas funciones de utilidad.
var doSomething = function(num) { return num + 1; } exports.doSomething = doSomething;
Entonces solicítelo según sea necesario
var doSomething = require('./util.js').doSomething;
fuente
Utils.js con la última sintaxis de Javascript ES6
Crea el
Utils.js
archivo así con múltiples funciones, etc.const someCommonValues = ['common', 'values']; export const doSomethingWithInput = (theInput) => { //Do something with the input return theInput; }; export const justAnAlert = () => { alert('hello'); };
Luego, en los componentes que desea utilizar las funciones util, importe las funciones específicas que sean necesarias. No tienes que importar todo
import {doSomethingWithInput, justAnAlert} from './path/to/utils.js/file'
Y luego use estas funciones dentro del componente como este:
justAnAlert(); <p>{doSomethingWithInput('hello')}</p>
fuente
/file
al final de la línea de importación?Si desea manipular el estado en las funciones auxiliares, siga esto:
Cree un archivo Helpers.js:
export function myFunc(){ return this.state.name; //define it according to your needs }
Importe la función auxiliar en su archivo de componente:
import {myFunc} from 'path-to/Helpers.js'
En su constructor agregue esa función auxiliar a la clase
constructor(){ this.myFunc = myFunc.bind(this) }
En tu función de render, úsala:
render(){ <div>{this.myFunc()}</div> }
fuente
Aquí hay algunos ejemplos sobre cómo puede reutilizar una función (
FetchUtil.handleError
) en un componente React (App
).Solución 1: uso de la sintaxis del módulo CommonJS
module.exports = { handleError: function(response) { if (!response.ok) throw new Error(response.statusText); return response; }, };
Solución 2: uso de "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;
Nota: Si está utilizando React v15.4 (o inferior), debe importar de la
createClass
siguiente manera:import React from 'react'; const FetchUtil = React.createClass({});
Fuente: https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactcreateclass
Componente (que reutiliza FetchUtil)
componentes / 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;
fuente
Otra opción sólida además de crear un archivo util sería utilizar un componente de orden superior para crear un
withComponentMapper()
contenedor. Este componente tomaría un componente como parámetro y lo devolvería con lacomponentMapper()
función transmitida como prop.Esto se considera una buena práctica en React. Puede averiguar cómo hacerlo en detalle aquí.
fuente
Suena como una función de utilidad, en ese caso, ¿por qué no ponerla en un módulo de utilidad estático separado?
De lo contrario, si usa un transpilador como Babel, puede hacer uso de los métodos estáticos de es7:
class MyComponent extends React.Component { static someMethod() { ...
O bien, si está usando React.createClass, puede usar el objeto estático :
var MyComponent = React.createClass({ statics: { customMethod: function(foo) { return foo === 'bar'; } }
Sin embargo, no recomiendo esas opciones, no tiene sentido incluir un componente para un método de utilidad.
Además, no debería pasar un método a través de todos sus componentes como apoyo, ya que los acoplará estrechamente y hará que la refactorización sea más dolorosa. Aconsejo un módulo de utilidad simple y antiguo.
La otra opción es usar un mixin para extender la clase, pero no lo recomiendo ya que no puede hacerlo en es6 + (y no veo el beneficio en este caso).
fuente
React.createClass
está en desuso desde React 15.5.0. create-react-app sugiere el uso del módulo npm en sucreate-react-class
lugar.doSomething.js
, por ejemplo , o un archivo con múltiples funciones de "utilidad" similares, por ejemplo,utils.js
e importaría esas funciones donde necesite usarlasA continuación, mostraré dos estilos y querrá elegir según la relación entre la lógica de los componentes.
Estilo 1: componentes relativamente relacionados se pueden crear con referencias de devolución de llamada, como esta, en
./components/App.js
...<SomeItem ref={(instance) => {this.childA = instance}} /> <SomeOtherItem ref={(instance) => {this.childB = instance}} />
Y luego puedes usar funciones compartidas entre ellos como este ...
this.childA.investigateComponent(this.childB); // call childA function with childB as arg this.childB.makeNotesOnComponent(this.childA); // call childB function with childA as arg
Estilo 2: los componentes de tipo util pueden crear así, en
./utils/time.js
...export const getTimeDifference = function (start, end) { // return difference between start and end }
Y luego pueden ser usar así, en
./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")); } }
¿Cuál usar?
Si la lógica está relativamente relacionada (solo se usan juntos en la misma aplicación), entonces debe compartir estados entre componentes. Pero si su lógica está relacionada de forma distante (es decir, utilidad matemática, utilidad de formato de texto), entonces debe crear e importar funciones de clase util.
fuente
¿No deberías usar un Mixin para esto? Ver https://facebook.github.io/react/docs/reusable-components.html
Aunque están cayendo en desgracia, consulte https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750
Podría ser útil
fuente