React에서 전역 변수를 선언하는 방법은 무엇입니까?


106

i18n구성 요소 (앱에로드되는 첫 번째 구성 요소)에서 번역 개체를 한 번 초기화했습니다 . 다른 모든 구성 요소에는 동일한 개체가 필요합니다. 모든 구성 요소에서 다시 초기화하고 싶지 않습니다. 주위는 무엇입니까? 창 범위에서 사용할 수 있도록 만드는 것은 render()방법 에서 사용해야하므로 도움이되지 않습니다 .

i18n 특정 솔루션이 아닌 이러한 문제에 대한 일반적인 솔루션을 제안하십시오.


1
데이터 또는 상태를 전역 적으로 처리 할 수있는 Redux또는 Flux라이브러리를 사용할 수 있습니다. 모든 구성 요소를 쉽게 통과 할 수 있습니다
vistajess

다른 방법은 없나요? 리 액트 프레임 워크없이 프로젝트를 시작했습니다. 리 액트 초기 였기 때문입니다. 이제 모든 구성 요소를 Redux 저장소에 연결하려면 엄청난 노력이 필요합니다.
sapy

3
React -Global 작업을 원하십니까?
TwoStraws 2015

답변:


50

Context 를 사용해 보지 않겠 습니까?

상위 구성 요소에서 전역 컨텍스트 변수를 선언 할 수 있으며이 변수는을 통해 구성 요소 트리에서 액세스 할 수 있습니다 this.context.varname. 부모 구성 요소 를 지정 childContextTypes하고 getChildContext그 후에 contextTypes는 자식 구성 요소를 지정하여 모든 구성 요소에서이를 사용 / 수정할 수 있습니다 .

그러나 문서에 언급 된대로 다음 사항에 유의하십시오.

명확한 코드를 작성할 때 전역 변수를 피하는 것이 가장 좋은 것처럼 대부분의 경우 컨텍스트를 사용하지 않아야합니다. 특히, "타이핑을 저장"하고 명시적인 props를 전달하는 대신 사용하기 전에 두 번 생각하십시오.


30
닫기 . 그러나 모든 구성 요소에는 부모 자식 관계가 없으며 컨텍스트는 해당 트리 이상으로 작동하지 않습니다. 응용 프로그램에서 i18n을 원합니다.
sapy

@sapy 이것이 i18n을 컨텍스트 변수가 아닌 redux 상태로 사용해야하는 이유입니다. 여기 내 대답을 참조하십시오. stackoverflow.com/questions/33413880/…
Fareed Alnamrouti

9
끔찍한 대답.
r3wt

내 옆에서 나는 대신, 특별히 큰 Apps에 REDUX를 사용하는 것이 좋습니다
호스 니 벤

37

반응을 넘어서

가져 오기가 이미 글로벌 이라는 사실을 모를 수 있습니다 . 객체 (싱글 톤)를 내 보내면 import 문으로 전역 적으로 액세스 할 수 있으며 전역 적으로 수정할 수도 있습니다 .

무언가를 전역 적으로 초기화하고 싶지만 한 번만 수정되도록하려면 처음에 수정 가능한 속성 이있는이 싱글 톤 접근 방식 을 사용할 수 있지만 처음 사용한 Object.freeze후에 사용 하여 초기화 시나리오에서 변경 불가능 하도록 할 수 있습니다.

const myInitObject = {}
export default myInitObject

그런 다음 그것을 참조하는 init 메소드에서 :

import myInitObject from './myInitObject'
myInitObject.someProp = 'i am about to get cold'
Object.freeze(myInitObject)

myInitObject그것이 어디서든 참조 할 수 여전히 글로벌 될 것입니다 가져 오기로 하지만 냉동을 유지하고 누군가 시도를 수정하는 경우에 발생합니다.

react-create-app을 사용하는 경우

(실제로 찾고 있던 것)이 시나리오에서는 환경 변수를 참조 할 때 전역 개체를 깨끗하게 초기화 할 수도 있습니다.

프로젝트의 루트에 접두사가 붙은 변수 를 사용 하여 .env 파일을 만드는 REACT_APP_것은 매우 훌륭합니다. process.env.REACT_APP_SOME_VAR필요에 따라 JS 및 JSX 내에서 참조 할 수 있으며 설계 상 변경할 수 없습니다.

이렇게하면 window.myVar = %REACT_APP_MY_VAR%HTML 로 설정할 필요가 없습니다 .

Facebook에서 직접 이에 대한 더 유용한 세부 정보를 참조하십시오.

https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables


6
이것은 솔직히 훌륭한 팁입니다. Server Side Rendering을 사용하고 있기 때문에 인증 토큰에 문제가있었습니다. 첫 번째로드에서 localstorage에서로드 한 다음 가져올 수있는 별도의 구성 파일에 저장했습니다. 좋은 대답입니다.
Eight

1
이것이 지금까지 최고의 답변입니다!
thiloilg

33

권장하지는 않지만 .... 앱 클래스에서 componentWillMount를 사용하여 전역 변수를 추가 할 수 있습니다.

componentWillMount: function () {
    window.MyVars = {
        ajax: require('../helpers/ajax.jsx'),
        utils: require('../helpers/utils.jsx')
    };
}

여전히 이것을 해킹이라고 생각하지만 작업을 완료합니다.

btw componentWillMount는 렌더링 전에 한 번 실행됩니다. 자세한 내용은 https://reactjs.org/docs/react-component.html#mounting-componentwillmount를 참조하십시오.


1
특정 사용 사례에 대한 해킹입니다. 회사에서 React 앱을 다른 비 React 앱의 컨텍스트에 통합하고 있습니다. 이는 소비 앱에 대한 공개 메서드를 노출하는 좋은 방법 인 것 같습니다. 내가 잘못? 더 좋은 방법이 있습니까?
mccambridge

2
또한 componentWillMount더 이상 사용되지 않습니다. reactjs.org/blog/2018/03/27/update-on-async-rendering.html
RyanNerd

@mccambridge 나는 이것이 늦었다는 것을 알고 있지만 비 React 앱에서 React로 정보를 보내기 위해 호출하는 함수를 보낼 것입니다. Btw, iframe으로 할 수 있습니다.
Nic Szerman

6

다음 내용으로 ./src 폴더에 "config.js"라는 파일을 만듭니다.

module.exports = global.config = {
    i18n: {
        welcome: {
            en: "Welcome",
            fa: "خوش آمدید"
        }
        // rest of your translation object
    }
    // other global config variables you wish
};

기본 파일 "index.js"에 다음 행을 입력하십시오.

import './config';

개체가 필요한 모든 곳에서 다음을 사용하십시오.

global.config.i18n.welcome.en

5

webpack에 전역 변수를 유지할 수 있습니다. webpack.config.js

externals: {
  'config': JSON.stringify(GLOBAL_VARIABLE: "global var value")
}

js 모듈에서 다음과 같이 읽을 수 있습니다.

var config = require('config')
var GLOBAL_VARIABLE = config.GLOBAL_VARIABLE

이것이 도움이되기를 바랍니다.



2

react https://facebook.github.io/react/docs/reusable-components.html#mixins 에서 mixins를 사용할 수 있습니다 .


7
참고 : ES6 구문 (현재 권장 됨) 또는 순수 구성 요소를 사용하는 경우 믹스 인을 사용할 수 없습니다. 권장 사항은 구성 요소를 구성하는 것입니다. medium.com/@dan_abramov/…
Aren

1
이것은 당신이 당신의 논리를 중앙 집중화 이상 (예를 들어, 로컬 스토리지 또는 클라이언트 측 DB) 저장의 플럭스 다른 유형으로 이동할 수 있습니다 다음으로 좋은 생각입니다
dcsan

2
이 답변은 코드 샘플을 포함하도록 확장되어야합니다. 링크가 끊어 질 수 있습니다.
vapcguy

0

여기에 현대적인 접근 방식은 사용이며, globalThis우리는 우리의 걸린, 반작용 기본 응용 프로그램.

globalThis 이제 ...에 포함되어 있습니다.


appGlobals.ts

// define our parent property accessible via globalThis. Also apply the TypeScript type.
var app: globalAppVariables;

// define the child properties and their types. 
type globalAppVariables = {
  messageLimit: number;
  // more can go here. 
};

// set the values.
globalThis.app = {
  messageLimit: 10,
  // more can go here.
};


// Freeze so these can only be defined in this file.
Object.freeze(globalThis.app);


App.tsx ( 기본 진입 점 파일 )

import './appGlobals'

// other code


anyWhereElseInTheApp.tsx

const chatGroupQuery = useQuery(GET_CHAT_GROUP_WITH_MESSAGES_BY_ID, {
  variables: {
    chatGroupId,
    currentUserId: me.id,
    messageLimit: globalThis.app.messageLimit, // 👈 used here.
  },
});

-6

나는 그들이이 "React Context"에 대해 무슨 말을하려고하는지 모르겠다. 그들은 나에게 그리스어로 말하고있다. 그러나 내가 한 방법은 다음과 같다.

동일한 페이지에서 함수 간 값 전달

생성자에서 setter를 바인딩합니다.

this.setSomeVariable = this.setSomeVariable.bind(this);

그런 다음 생성자 바로 아래에 함수를 선언합니다.

setSomeVariable(propertyTextToAdd) {
    this.setState({
        myProperty: propertyTextToAdd
    });
}

설정하고 싶을 때 this.setSomeVariable("some value");

(당신은 도망 칠 수도 있습니다 this.state.myProperty = "some value";)

당신이 그것을 얻고 싶을 때, 전화하십시오 var myProp = this.state.myProperty;

사용 alert(myProp);하면 some value.

페이지 / 구성 요소간에 값을 전달하는 추가 스캐 폴딩 방법

모델을 this(기술적으로 this.stores) 할당 할 수 있으므로 다음을 사용하여 참조 할 수 있습니다 this.state.

import Reflux from 'reflux'
import Actions from '~/actions/actions`

class YourForm extends Reflux.Store
{
    constructor()
    {
        super();
        this.state = {
            someGlobalVariable: '',
        };
        this.listenables = Actions;
        this.baseState = {
            someGlobalVariable: '',
        };
    }

    onUpdateFields(name, value) {
        this.setState({
            [name]: value,
        });
    }

    onResetFields() {
        this.setState({
           someGlobalVariable: '',
        });
    }
}
const reqformdata = new YourForm

export default reqformdata

이 폴더 storesyourForm.jsx.

그런 다음 다른 페이지에서이 작업을 수행 할 수 있습니다.

import React from 'react'
import Reflux from 'reflux'
import {Form} from 'reactstrap'
import YourForm from '~/stores/yourForm.jsx'

Reflux.defineReact(React)

class SomePage extends Reflux.Component {
    constructor(props) {
        super(props);
        this.state = {
            someLocalVariable: '',
        }
        this.stores = [
            YourForm,
        ]
    }
    render() {

        const myVar = this.state.someGlobalVariable;
        return (
            <Form>
                <div>{myVar}</div>
            </Form>
        )
    }
}
export default SomePage

다음 this.state.someGlobalVariable과 같은 기능을 사용하여 다른 구성 요소를 설정 한 경우 :

setSomeVariable(propertyTextToAdd) {
    this.setState({
       myGlobalVariable: propertyTextToAdd
   });
}

생성자에서 다음을 사용하여 바인딩합니다.

this.setSomeVariable = this.setSomeVariable.bind(this);

의 값은 위에 표시된 코드 propertyTextToAddSomePage사용하여 표시됩니다 .


3
죄송합니다 새로운 여기에 존재하지만, 난 그냥 반작용 배우고을위한하지 않도록이 답변은 많은을 downvoted받을 이유
someoneuseless에게

3
@someoneuseless 정확히! 그래서 내가 삭제를 거부하고 대중들에게 코우 트하는 것입니다. 그들이 "컨텍스트"(그것이 무엇이든간에)와 다른 재미있는 물건을 사용하고 싶어한다고해서 모든 사람이 필요로하는 것은 아닙니다. 하이 파이브!
vapcguy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.