Есть ли способ использовать функции внутри компонента или общего файла в реакции? - PullRequest
0 голосов
/ 07 января 2020

Я пытаюсь получить доступ к функциям внутри компонента, основанного на классах, который можно использовать на протяжении всего проекта. Причина, по которой я думаю, что классы основаны на том, что эти запросы / функции требуют вызова метода init () перед доступом к таким данным каждый раз . Например:

SharedSDKFile. js

import Facebook from 'facebook-sdk';

class SharedSDKFile extends Component {
   constructor() {
      Facebook.init({// init some stuff})
   }

  async user() {
    return Facebook.getUser()
  }

  render() {
    return(// ????????????????)
  }
}

// *****************************************************
Dashboard.js
// *****************************************************
import Facebook from '../{path}/SharedSDKFile'

const dashboard = () => {
   let [person,setPerson] = useState()

// cool function to get and set Users
   let user = getUser();
   setPerson(user)
// End of cool function

}

Я даже пытался структурировать его с помощью другого подхода, просто экспортируя функции

SharedSDKFile. js

async init() {
  // init stuff
}

export const getUser = async(data) => {
   init()
   // get user
}

// *****************************************************
Dashboard.js
// *****************************************************
import {getUser}from '../{path}/SharedSDKFile'

const dashboard = () => {
 let [person,setPerson] = useState()

// cool function to get and set Users
   let user = getUser();
   setPerson(user)
// End of cool function
}

Пока работает файл, который экспортирует вашу функцию, состояние исчезает при перезагрузке / обновлении sh.

Возможно, есть лучшее решение для этого, и я думаю об этом. Я рассмотрел избыточность или локальное состояние, но у меня будет несколько функций внутри sharedSDKFile. js, которые потребуют нескольких действий и редукторов ...

Я пытаюсь предотвратить вызов нескольких init () и избыточности, если я Я могу импортировать, например, FacebookSDK в каждом файле, который в этом нуждается.

1 Ответ

0 голосов
/ 07 января 2020

Мне нравится использовать контекстный одноэлементный подход, чтобы изолировать внешние сервисы, которые могут использоваться во всем приложении, что может или не может соответствовать тому, что вы хотите сделать. В нем используются провайдеры / потребители контекста, а не такие вещи, как Redux.

Это не полная картина, но, надеюсь, дает некоторое представление о том, как подход может работать для вас:

FacebookContext . js (или AWSContext. js, или ... любой конкретный c сервис)

import React, { Component, createContext } from "react";
import Facebook from "facebook-sdk";

export const FacebookContext = createContext({});

class FacebookProvider extends Component {
  state = {
    user: null,
    // whatever else you need to expose to calling components, like
    // lastLoggedIn: null,
    // verified: false,
    // ...
  };

  componentDidMount() {
    Facebook.init({
      // init some stuff
    })
  }

  setUser = user => {
    this.setState({
      user
    });
  }

  // whatever other methods/data you want this class to expose

  render() {
    return (
      <FacebookContext.Provider
        value={{
          user: this.state.user // available with FacebookContext.user
          // other state values
          //
          setUser: this.setUser // available with FacebookContext.setUser
          // other class methods
        }}
      >
        {this.props.children}
      </FacebookContext.Provider>
    );
  }
}

export default FacebookProvider;

Добавьте провайдера в файл приложения верхнего уровня, что-то например, в приложении. js:

import FacebookProvider from "/path/to/FacebookContext";

// ...

class App extends React.Component {
  render() {
    return (
      <FacebookProvider>
        {yourAppRenderStuff}
      </FacebookProvider>
    );
  }
}

Добавьте получателя к любым вызывающим компонентам:

import { FacebookContext } from "/path/to/FacebookContext";

class SomethingComponent extends Component {
  componentDidMount() {
    const { facebookContext } = this.props;

    facebookContext.setUser(`some user`);// available in other components

    console.log(facebookContext.user);// broadcasted to other components
  }

  render() {
    return (
      <></>
    );
  }
}

const Something = () => (
  <FacebookContext.Consumer>
    {facebookContext => (
      <SomethingComponent facebookContext={facebookContext} />
    )}
  </FacebookContext.Consumer>
);

export default Something;
...