বিক্রিয়া উপাদানটির বাইরে রডেক্স স্টোর অ্যাক্সেস করার সর্বোত্তম উপায় কী?


191

@connectআমি যখন প্রতিক্রিয়া উপাদানটির মধ্যে দোকানে অ্যাক্সেস করার চেষ্টা করি তখন দুর্দান্ত কাজ করে। তবে কীভাবে আমি কোডের অন্য কিছুটিতে এটি অ্যাক্সেস করব। উদাহরণস্বরূপ: আসুন বলি যে আমি আমার অক্ষগুলি তৈরি করতে একটি অনুমোদনের টোকেন ব্যবহার করতে চাই যা আমার অ্যাপ্লিকেশনে বিশ্বব্যাপী ব্যবহার করা যেতে পারে, এটি অর্জনের সর্বোত্তম উপায় কী হবে?

এটা আমার api.js

// tooling modules
import axios from 'axios'

// configuration
const api = axios.create()
api.defaults.baseURL = 'http://localhost:5001/api/v1'
api.defaults.headers.common['Authorization'] = 'AUTH_TOKEN' // need the token here
api.defaults.headers.post['Content-Type'] = 'application/json'

export default api

এখন আমি আমার স্টোর থেকে একটি ডেটা পয়েন্ট অ্যাক্সেস করতে চাই, এখানে যদি এটি ব্যবহার করে আমি একটি প্রতিক্রিয়া উপাদানটির মধ্যে এটি ব্যবহার করার চেষ্টা করি তবে এটি দেখতে কেমন লাগে? @connect

// connect to store
@connect((store) => {
  return {
    auth: store.auth
  }
})
export default class App extends Component {
  componentWillMount() {
    // this is how I would get it in my react component
    console.log(this.props.auth.tokens.authorization_token) 
  }
  render() {...}
}

কোন অন্তর্দৃষ্টি বা ওয়ার্কফ্লো নিদর্শন আছে?


আপনি কি চাইছেন না আপনি অক্ষের উদাহরণটি একটি রেডেক্স মিডলওয়্যারের সাথে বাস করবেন? এটি আপনার সমস্ত অ্যাপ্লিকেশন দ্বারা এইভাবে উপলভ্য হবে
এমরিস মাইরোইন

আপনি আমদানি করতে পারেন apiমধ্যে Appশ্রেণী এবং অনুমোদন টোকেন আপনি কি করতে পারেন পাওয়ার পর api.defaults.headers.common['Authorization'] = this.props.auth.tokens.authorization_token;, এবং একই সময়ে পাশাপাশি, localStorage এটা সঞ্চয় করে নেবে তাই ব্যবহারকারী রিফ্রেশ পাতা, আপনি না পরীক্ষা করতে যখন যদি টোকেন localStorage এবং যদি থাকে তাহলে করতে পারেন না, আপনি এটি সেট করতে পারেন।, আমি মনে করি আপনি এপিআই মডিউলটি পাওয়ার সাথে সাথেই টোকেন সেট করা ভাল হবে।
ধ্রুব কুমার ঝা

1
ড্যান আবরোমভ এখানে ইস্যু কাতারে একটি উদাহরণ সরবরাহ করেছেন: github.com/reactjs/redux/issues/916
ক্রিশ্চলি

1
আপনার যদি কেবলমাত্র কোনও নির্দিষ্ট রেডুসার থেকে কোনও নির্দিষ্ট রাজ্যে অ্যাক্সেসের প্রয়োজন হয় তবে আপনি রেডেক্স-নামক- হ্রাসকারীদের দিয়ে চেষ্টা করতে পারেন এটি আপনাকে যে কোনও জায়গা থেকে সর্বশেষতম রাজ্যে অ্যাক্সেস করতে দেয়।
মাইল_স্রষ্টিয়ান

উত্তর:


146

আপনি যে মডিউলটি দিয়েছিলেন সেখান থেকে স্টোরটি রফতানি করুন createStore। তারপরে আপনাকে আশ্বাস দেওয়া হয়েছে যে এটি উভয়ই তৈরি হবে এবং বৈশ্বিক উইন্ডো স্পেসকে দূষিত করবে না।

MyStore.js

const store = createStore(myReducer);
export store;

অথবা

const store = createStore(myReducer);
export default store;

MyClient.js

import {store} from './MyStore'
store.dispatch(...)

বা যদি আপনি ডিফল্ট ব্যবহার করেন

import store from './MyStore'
store.dispatch(...)

একাধিক স্টোর ব্যবহারের ক্ষেত্রে

আপনার যদি কোনও স্টোরের একাধিক উদাহরণ প্রয়োজন হয় তবে একটি কারখানার ফাংশন রফতানি করুন। আমি এটি তৈরির প্রস্তাব দিচ্ছি async(প্রত্যাবর্তন promise)।

async function getUserStore (userId) {
   // check if user store exists and return or create it.
}
export getUserStore

ক্লায়েন্টে (একটি asyncব্লকে)

import {getUserStore} from './store'

const joeStore = await getUserStore('joe')

47
আইসমোর্ফিক অ্যাপ্লিকেশনগুলির জন্য সতর্কতা: এই সার্ভার-সাইডটি করা আপনার সমস্ত ব্যবহারকারীদের জুড়ে রেডেক্স স্টোরটি ভাগ করে নেবে !!!
লরেন্স ওয়াগারফিল্ড

6
প্রশ্নটি স্পষ্টভাবে "ব্রাউজার" কেও বর্ণনা করে না। যেহেতু রেডাক্স এবং জাভাস্ক্রিপ্ট উভয়ই সার্ভার বা ব্রাউজারে ব্যবহার করা যেতে পারে, তাই এটি নির্দিষ্ট করা অনেক বেশি নিরাপদ।
লরেন্স ওয়াগারফিল্ড

7
রফতানির দোকানে চক্রীয় আমদানির একটি দুঃস্বপ্ন তৈরি বলে মনে হয়, ক্রিয়েস্টোর আপনার হ্রাসকারীদের অন্তর্ভুক্ত করে, যার জন্য আপনার ক্রিয়নের প্রয়োজন হয় (কমপক্ষে অ্যাকশন টাইপ এনুম এবং অ্যাকশন ইন্টারফেস), যা স্টোর আমদানির চেষ্টা করে এমন কোনও কিছু আমদানি করতে হবে না। সুতরাং আপনাকে অবশ্যই আপনার হ্রাসকারী বা ক্রিয়াকলাপের মধ্যে স্টোর ব্যবহার করা উচিত নয় (বা চক্রীয় আমদানির আশেপাশে অন্য কোনও উপায়ে লড়াই করা উচিত।)
এলফ

6
এটি সঠিক উত্তর, তবে আপনি যদি (আমার মতো) দোকানে কোনও ক্রিয়া প্রেরণের পরিবর্তে পড়তে চান তবে আপনাকে কল করতে হবেstore.getState()
জুয়ান জোসে রামেরেজ

3
হ্যাঁ, "অ্যাক্সেস রিডেক্স স্টোর" সম্পর্কিত আমার ব্যাখ্যাটি ছিল "পড়া" স্টোর। অন্যকে সাহায্য করার চেষ্টা করছি।
জুয়ান জোসে রামারেজ

47

একটি সমাধান খুঁজে পেয়েছি। তাই আমি আমার এপিআই ব্যবহার করে দোকানটি আমদানি করি এবং সেখানে এটিতে সাবস্ক্রাইব করি। এবং সেই শ্রোতার ফাংশনে আমি আমার নতুন প্রাপ্ত টোকেনের সাথে অক্ষরগুলির গ্লোবাল ডিফল্ট সেট করেছি।

এটি আমার নতুন api.jsদেখতে দেখতে:

// tooling modules
import axios from 'axios'

// store
import store from '../store'
store.subscribe(listener)

function select(state) {
  return state.auth.tokens.authentication_token
}

function listener() {
  let token = select(store.getState())
  axios.defaults.headers.common['Authorization'] = token;
}

// configuration
const api = axios.create({
  baseURL: 'http://localhost:5001/api/v1',
  headers: {
    'Content-Type': 'application/json',
  }
})

export default api

হতে পারে এটি আরও উন্নত করা যেতে পারে, কারণ বর্তমানে এটি কিছুটা অস্বস্তিকর বলে মনে হচ্ছে। আমি পরে যা করতে পারি তা হ'ল আমার স্টোরটিতে একটি মিডওয়্যার যুক্ত করা এবং সেখানে এবং সেখানে টোকেন সেট করা।


1
আপনার store.jsফাইলটি দেখতে দেখতে কী ভাগ করে নিতে পারেন?
ভিক

ঠিক আমি যা খুঁজছিলাম তার জন্য ধন্যবাদ, একটি টন @ সুবোধকে
সালুজা

1
আমি জানি প্রশ্নটি পুরানো, তবে আপনি নিজের উত্তরটি সঠিক হিসাবে গ্রহণ করতে পারেন। এটি অন্যদের জন্য অনুসন্ধান করা আপনার উত্তরকে আরও সহজ করে যা শেষ পর্যন্ত এখানে আসতে পারে।
ফিলিপ মার্কার

3
যখন আমি কোনও উপাদান বা কোনও ফাংশনের বাইরে স্টোর অ্যাক্সেস করার চেষ্টা করি তখন আমি " টাইপআরার : WEBPACK_IMPORTED_MODULE_2__store_js .b অপরিজ্ঞাত " পেয়েছি । কেন যে কোন সাহায্য?
বেন

21

তুমি ব্যবহার করতে পার storecreateStore ফাংশন থেকে ফিরে আসা জিনিসটি (যা অ্যাপ্লিকেশন শুরুতে আপনার কোডটিতে ইতিমধ্যে ব্যবহার করা উচিত)। store.getState()পদ্ধতির সাথে বর্তমান অবস্থা পেতে বা store.subscribe(listener)স্টোর আপডেটের সাবস্ক্রাইব করতে আপনি এই অবজেক্টটি ব্যবহার করতে পারেন ।

আপনি windowযদি সত্যিকারভাবে এটি চান তবে অ্যাপ্লিকেশনটির যে কোনও অংশ থেকে এটি অ্যাক্সেস করার জন্য আপনি এই বস্তুকে সম্পত্তিতে সংরক্ষণ করতে পারেন ( window.store = store)

রেডাক্স ডকুমেন্টেশনে আরও তথ্য পাওয়া যাবে ।


19
সংরক্ষণ করতে ধরণ হল hacky শোনাচ্ছে storeথেকেwindow
ভিক

3
@ বিজয় নিশ্চিত যে এটি :) এবং সাধারণত আপনি এটি করতে চান না। আমি কেবল উল্লেখ করতে চেয়েছিলাম যে আপনি এই ভেরিয়েবলটি দিয়ে যা কিছু করতে পারেন তা করতে পারেন। সম্ভবত সবচেয়ে ভাল ধারণাটি হ'ল ফাইলটিতে এটি সংরক্ষণ করা যেখানে আপনি আপনার "ক্রিয়েস্টোর" জীবন তৈরি করেছেন এবং তারপরে এটিকে কেবল আমদানি করুন।
ট্র্যাশ জেনারেটর

আমার একাধিক আইফ্রেমে রয়েছে যা অন্য আইফ্রেমের স্থিতিতে অ্যাক্সেস প্রয়োজন। আমি জানি এটাকে হ্যাকি তবে আমি মনে করি উইন্ডোতে স্টোর রাখা আইফ্রেমে মেসেজ ব্যবহার করার চেয়ে ভাল। কোন চিন্তা?? @ ভিক @ ট্র্যাশজনার?
শান ম্যালটার


9

@ সানচিট প্রস্তাবিত মিডলওয়্যারের মতো আপনি যদি ইতিমধ্যে বিশ্বব্যাপী নিজের অক্ষরগুলির উদাহরণটি সংজ্ঞায়িত করেন তবে এটি একটি দুর্দান্ত সমাধান ।

আপনি মিডলওয়্যার এর মতো তৈরি করতে পারেন:

function createAxiosAuthMiddleware() {
  return ({ getState }) => next => (action) => {
    const { token } = getState().authentication;
    global.axios.defaults.headers.common.Authorization = token ? `Bearer ${token}` : null;

    return next(action);
  };
}

const axiosAuth = createAxiosAuthMiddleware();

export default axiosAuth;

এবং এটি এর মতো ব্যবহার করুন:

import { createStore, applyMiddleware } from 'redux';
const store = createStore(reducer, applyMiddleware(axiosAuth))

এটি প্রতিটি ক্রিয়ায় টোকেন সেট করবে তবে আপনি কেবল সেই ক্রিয়াকলাপের জন্য শুনতে পারেন যা উদাহরণস্বরূপ টোকেন পরিবর্তন করে।


3

টাইপস্ক্রিপ্ট ২.০ এর জন্য এটি দেখতে এরকম হবে:

MyStore.ts

export namespace Store {

    export type Login = { isLoggedIn: boolean }

    export type All = {
        login: Login
    }
}

import { reducers } from '../Reducers'
import * as Redux from 'redux'

const reduxStore: Redux.Store<Store.All> = Redux.createStore(reducers)

export default reduxStore;

MyClient.tsx

import reduxStore from "../Store";
{reduxStore.dispatch(...)}

3
আপনি যদি ভোট দিচ্ছেন, দয়া করে কেন একটি মন্তব্য যুক্ত করুন।
ওগ্লাস

3
ডাউন ভোট দিয়েছে কারণ আপনার উত্তরটিতে ব্যাখ্যার অভাব রয়েছে এবং জাভাস্ক্রিপ্টের চেয়ে টাইপস্ক্রিপ্ট ব্যবহার করা হয়েছে।
উইল

2
@ উইল কেন বলার জন্য আপনাকে ধন্যবাদ। ইমো কোডটির নির্দিষ্টকরণের প্রয়োজন নেই তবে আপনি যদি নির্দিষ্ট কিছু ব্যাখ্যা করতে চান তবে দয়া করে কী বলুন। টাইপসক্রিপটি প্রকৃতপক্ষে ব্যবহৃত হয় তবে টাইপগুলি সরানো থাকলে একই কোড ES6 এ কোনও সমস্যা ছাড়াই চলবে।
ওগ্লাস 21

মনে রাখবেন এটি খুব খারাপ হবে যদি আপনি সেভ-সাইড-রেন্ডারিং করছেন, এটি সমস্ত অনুরোধের সাথে রাষ্ট্র ভাগ করে নেবে।
রব ইভানস

2

এটি কিছুটা দেরিতে হতে পারে তবে আমি মনে করি axios.interceptorsনীচের মতো ব্যবহার করা সবচেয়ে ভাল উপায় । আপনার প্রকল্পের সেটআপের ভিত্তিতে আমদানি ইউআরএল পরিবর্তিত হতে পারে।

index.js

import axios from 'axios';
import setupAxios from './redux/setupAxios';
import store from './redux/store';

// some other codes

setupAxios(axios, store);

setupAxios.js

export default function setupAxios(axios, store) {
    axios.interceptors.request.use(
        (config) => {
            const {
                auth: { tokens: { authorization_token } },
            } = store.getState();

            if (authorization_token) {
                config.headers.Authorization = `Bearer ${authorization_token}`;
            }

            return config;
        },
       (err) => Promise.reject(err)
    );
}

1

হুক দিয়ে এটি করা। আমি একই ধরণের সমস্যায় পড়েছি, তবে আমি হুকস দিয়ে রিঅ্যাক্ট-রিডেক্স ব্যবহার করছিলাম। স্টোর থেকে / থেকে তথ্য পুনরুদ্ধার / প্রেরণে উত্সর্গীকৃত প্রচুর কোড সহ আমি আমার ইন্টারফেস কোডটি (অর্থাত্‍ উপাদানগুলি প্রতিক্রিয়া জানাতে) লর্ড আপ করতে চাইনি। বরং আমি তথ্য পুনরুদ্ধার এবং আপডেট করার জন্য জেনেরিক নামগুলির সাথে ফাংশন চাইছিলাম। আমার পথটি অ্যাপ্লিকেশনটির করা ছিল

const store = createSore(
   allReducers,
   window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
 );

নামে একটি মডিউল মধ্যে store.jsএবং যোগ করার exportআগে constএবং store.js মধ্যে স্বাভাবিক প্রতিক্রিয়া-redux আমদানির যোগ। ফাইল। তারপর, আমি এ আমদানি index.jsঅ্যাপ্লিকেশন স্তর, যা আমি তারপর index.js চলিত সঙ্গে আমদানি এ import {store} from "./store.js"শিশু উপাদান তারপর দোকান দিয়ে অ্যাক্সেস করা useSelector()এবং useDispatch()আঙ্গুলসমূহ।

অ-উপাদানগুলির সামনের শেষের কোডটিতে স্টোরটি অ্যাক্সেস করতে, আমি অ্যানালোগুলি আমদানি (অর্থাত্‍ import {store} from "../../store.js") ব্যবহার করি store.getState()এবং তারপরে ব্যবহৃত এবং store.dispatch({*action goes here*})পুনরুদ্ধার ও আপডেট করার জন্য পরিচালনা করি (এর, ক্রিয়া প্রেরণ)।


0

টোকেন অ্যাক্সেস করার একটি সহজ উপায় হ'ল লোকালস্টোরারেজে বা অ্যাসিঙ্কস্টোরারে রিঅ্যাক্ট নেটিভ সহ টোকন স্থাপন করা।

একটি প্রতিক্রিয়া নেটিভ প্রকল্পের সাথে উদাহরণের নীচে

authReducer.js

import { AsyncStorage } from 'react-native';
...
const auth = (state = initialState, action) => {
  switch (action.type) {
    case SUCCESS_LOGIN:
      AsyncStorage.setItem('token', action.payload.token);
      return {
        ...state,
        ...action.payload,
      };
    case REQUEST_LOGOUT:
      AsyncStorage.removeItem('token');
      return {};
    default:
      return state;
  }
};
...

এবং api.js

import axios from 'axios';
import { AsyncStorage } from 'react-native';

const defaultHeaders = {
  'Content-Type': 'application/json',
};

const config = {
  ...
};

const request = axios.create(config);

const protectedRequest = options => {
  return AsyncStorage.getItem('token').then(token => {
    if (token) {
      return request({
        headers: {
          ...defaultHeaders,
          Authorization: `Bearer ${token}`,
        },
        ...options,
      });
    }
    return new Error('NO_TOKEN_SET');
  });
};

export { request, protectedRequest };

ওয়েবের জন্য আপনি Window.localStorageঅ্যাসিঙ্কস্টোরেজের পরিবর্তে ব্যবহার করতে পারেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.