অ্যাকশন নির্মাতায় রেডাক্স রাজ্যে অ্যাক্সেস করছেন?


296

বলুন আমার নিম্নলিখিত রয়েছে:

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
  }
}

এবং সেই অ্যাকশন স্রষ্টার মধ্যে, আমি গ্লোবাল স্টোর রাজ্যে (সমস্ত হ্রাসকারী) অ্যাক্সেস করতে চাই। এটি করা কি আরও ভাল:

import store from '../store';

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
    items: store.getState().otherReducer.items,
  }
}

অথবা এটা:

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return (dispatch, getState) => {
    const {items} = getState().otherReducer;

    dispatch(anotherAction(items));
  }
}

উত্তর:


521

অ্যাকশন স্রষ্টাদের মধ্যে রাষ্ট্রের অ্যাক্সেস করা একটি ভাল ধারণা কিনা সে সম্পর্কে বিভিন্ন মতামত রয়েছে:

  • রেডাক্সের নির্মাতা ড্যান আব্রামভ মনে করেন এটি সীমাবদ্ধ হওয়া উচিত: "আপনার কাছে অনুরোধ করার আগে ক্যাশেড ডেটা যাচাই করা বা আপনার প্রমাণীকরণ হয়েছে কিনা তা পরীক্ষা করার জন্য (অন্য কথায়, শর্তাধীন প্রেরণ করা) যে কয়েকটি ব্যবহারের ক্ষেত্রে আমি তা গ্রহণযোগ্য বলে মনে করি use আমি মনে করি যে ক্ষণস্থায়ী তথ্য যেমন state.something.itemsএকটি কর্ম স্রষ্টা স্পষ্টভাবে বিরোধী প্যাটার্ন এবং নিরুৎসাহিত করা হয়, কারণ এটা পরিবর্তনের ইতিহাস আড়াল: যদি একটি বাগ সংশোধন করা হয় এবং itemsভুল হয়, এটা ট্রেস কঠিন যেখানে ঐ ভুল মান কারণ তারা থেকে আসা কোনও ক্রমের প্রতিক্রিয়া হিসাবে কোনও হ্রাসকারক দ্বারা সরাসরি গণনা না করে ইতিমধ্যে অ্যাকশনের অংশ So তাই যত্ন সহকারে এটি করুন ""
  • বর্তমান রেডাক্স রক্ষণাবেক্ষণকারী মার্ক এরিকসন বলেছেন যে এটি ঠিক আছে এবং এমনকি getStateথাঙ্কস ব্যবহার করতে উত্সাহিত করেছেন - এ কারণেই এটি বিদ্যমান । তিনি তার ব্লগ পোস্ট আইডিয়োমেটিক রেডাক্স: থিংস, সাগাস, অ্যাবস্ট্রাকশন এবং পুনঃব্যবহারযোগ্যতা সম্পর্কিত চিন্তাভাবনাগুলিতে অ্যাকশন স্রষ্টাদের কাছে রাষ্ট্রের অ্যাক্সেসের পক্ষে ও কলসগুলি নিয়ে আলোচনা করেছেন

যদি আপনার মনে হয় যে এটির আপনার প্রয়োজন আছে তবে আপনার প্রস্তাবিত উভয় পন্থা ভাল। প্রথম পদ্ধতির জন্য কোনও মিডলওয়্যারের প্রয়োজন নেই:

import store from '../store';

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
    items: store.getState().otherReducer.items,
  }
}

তবে আপনি দেখতে পাচ্ছেন যে এটি storeকিছু মডিউল থেকে রফতানি হওয়া সিঙ্গলটন হওয়ার উপর নির্ভর করে । আমরা এটির প্রস্তাব দিই না কারণ এটি আপনার অ্যাপ্লিকেশনটিতে সার্ভার রেন্ডারিং যুক্ত করা আরও কঠিন করে তোলে কারণ বেশিরভাগ ক্ষেত্রে সার্ভারে আপনি অনুরোধ অনুযায়ী আলাদা স্টোর রাখতে চান । সুতরাং প্রযুক্তিগতভাবে এই পদ্ধতির কাজ করার সময় আমরা কোনও মডিউল থেকে কোনও দোকান রফতানি করার পরামর্শ দিই না।

এ কারণেই আমরা দ্বিতীয় পদ্ধতির প্রস্তাব দিই:

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return (dispatch, getState) => {
    const {items} = getState().otherReducer;

    dispatch(anotherAction(items));
  }
}

এটির জন্য আপনাকে রেডাক্স থঙ্ক মিডলওয়্যার ব্যবহার করতে হবে তবে এটি ক্লায়েন্ট এবং সার্ভারে উভয়ই দুর্দান্ত কাজ করে works আপনি Redux Thunk সম্বন্ধে আরও পড়তে পারেন এবং কেন এটা এই ক্ষেত্রে প্রয়োজন এখানে

আদর্শভাবে, আপনার ক্রিয়াকলাপগুলি "চর্বি" হওয়া উচিত নয় এবং যতটা সম্ভব কম তথ্য থাকা উচিত, তবে আপনার নিজের প্রয়োগে যা আপনার পক্ষে সবচেয়ে ভাল কাজ করে তা নির্দ্বিধায় আপনার উচিত। রেডাক্স এফএকিউতে অ্যাকশন নির্মাতাদের এবং হ্রাসকারীদের মধ্যে সময় বিভক্ত করার যুক্তি সম্পর্কিত তথ্য রয়েছে এবং কখন getStateঅ্যাকশন স্রষ্টাকে ব্যবহার করা কার্যকর হতে পারে


5
আমার একটি পরিস্থিতি আছে যখন কোনও উপাদানতে কোনও কিছু নির্বাচন করা PUT বা POST কে ট্রিগার করতে পারে, নির্ভর করে দোকানে যদি উপাদানটির সাথে সম্পর্কিত ডেটা থাকে বা না থাকে। থানক-ভিত্তিক অ্যাকশন নির্মাতার পরিবর্তে উপাদানটিতে PUT / POST নির্বাচনের ব্যবসায়ের যুক্তি যুক্ত করা ভাল?
ভিসুবাস

3
সেরা অনুশীলন কি? আমি এখন একই ক্রিয়াকলাপের মুখোমুখি হয়েছি যেখানে আমি আমার অ্যাকশন স্রষ্টায় গেটস্টেট ব্যবহার করছি। আমার ক্ষেত্রে আমি কোনও ফর্মের জন্য মুলতুবি পরিবর্তন রয়েছে কিনা তা নির্ধারণ করতে এটি ব্যবহার করি (এবং যদি তাই হয় তবে আমি এমন কোনও ক্রিয়া পাঠাব যা সংলাপ দেখায়)।
আরনে এইচ। বিটুবেক্ক

42
অ্যাকশন স্রষ্টায় স্টোর থেকে পড়া ভাল। আমি আপনাকে একজন নির্বাচক ব্যবহার করতে উত্সাহিত করব যাতে আপনি সঠিক রাষ্ট্রের আকারের উপর নির্ভর না করে।
ড্যান আব্রামভ

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

2
ওহ মানুষ! আমি যে getState
রেডুক্স থাঙ্কটি

33

আপনার পরিস্থিতি সহজ হলে আপনি ব্যবহার করতে পারেন

import store from '../store';

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
    items: store.getState().otherReducer.items,
  }
}

তবে কখনও কখনও আপনার action creatorএকাধিক ক্রিয়া ট্রিগার করতে হবে

উদাহরণস্বরূপ async অনুরোধ যাতে আপনার REQUEST_LOAD REQUEST_LOAD_SUCCESS REQUEST_LOAD_FAILক্রিয়া দরকার

export const [REQUEST_LOAD, REQUEST_LOAD_SUCCESS, REQUEST_LOAD_FAIL] = [`REQUEST_LOAD`
    `REQUEST_LOAD_SUCCESS`
    `REQUEST_LOAD_FAIL`
]
export function someAction() {
    return (dispatch, getState) => {
        const {
            items
        } = getState().otherReducer;
        dispatch({
            type: REQUEST_LOAD,
            loading: true
        });
        $.ajax('url', {
            success: (data) => {
                dispatch({
                    type: REQUEST_LOAD_SUCCESS,
                    loading: false,
                    data: data
                });
            },
            error: (error) => {
                dispatch({
                    type: REQUEST_LOAD_FAIL,
                    loading: false,
                    error: error
                });
            }
        })
    }
}

দ্রষ্টব্য: অ্যাকশন স্রষ্টায় ফাংশন ফিরে পেতে আপনার রিডেক্স-থাঙ্ক দরকার


3
আমি কেবলই জিজ্ঞাসা করতে পারি যে রাষ্ট্রের 'লোডিং' এর স্থিতি সম্পর্কে কোনও চেক থাকা উচিত কিনা যাতে প্রথমটি শেষ হওয়ার সাথে সাথে অন্য এজ্যাক্স অনুরোধটি তৈরি না হয়?
জোটিডি 2

@ জোটিডি উদাহরণস্বরূপ লোডিং রাষ্ট্রের প্রেরণ সম্পন্ন হয়েছে। উদাহরণস্বরূপ আপনি যদি বোতামটি দিয়ে এই ক্রিয়াটি করেন, আপনি loading === trueসেখানে কিনা তা পরীক্ষা করে দেখুন এবং বোতামটি অক্ষম করে দিন।
ক্রোফ

4

আমি ব্লুমকার সাথে একমত আর্গুমেন্ট হিসাবে স্টোর থেকে প্রেরণ ফাংশনে প্রয়োজনীয় মানটি স্টোর রফতানির চেয়ে সহজ বলে মনে হয়। আমি এখানে একটি উদাহরণ তৈরি করেছি:

import React from "react";
import {connect} from "react-redux";
import * as actions from '../actions';

class App extends React.Component {

  handleClick(){
    const data = this.props.someStateObject.data;
    this.props.someDispatchFunction(data);
  }

  render(){
    return (
      <div>       
      <div onClick={ this.handleClick.bind(this)}>Click Me!</div>      
      </div>
    );
  }
}


const mapStateToProps = (state) => {
  return { someStateObject: state.someStateObject };
};

const mapDispatchToProps = (dispatch) => {
  return {
    someDispatchFunction:(data) => { dispatch(actions.someDispatchFunction(data))},

  };
}


export default connect(mapStateToProps, mapDispatchToProps)(App);

এই পদ্ধতিটি বেশ যৌক্তিক।
আহমেট şimşek

এটি করার সঠিক উপায় এবং আমি এটি কীভাবে করব। আপনার ক্রিয়া-স্রষ্টাকে পুরো রাজ্যটি জানা দরকার নেই, কেবল এটির সাথে প্রাসঙ্গিক।
অ্যাশ

3

আমি এটি উল্লেখ করতে চাই যে স্টোর থেকে পড়া খুব খারাপ নয় - স্টোরের উপর ভিত্তি করে কী করা উচিত তা সিদ্ধান্ত নেওয়া আরও অনেক সুবিধাজনক হতে পারে, তারপরে সমস্ত উপাদানকে স্থান দেওয়ার পরে এবং তার পরামিতি হিসাবে একটি অনুষ্ঠান. আমি ড্যানের সাথে সম্পূর্ণরূপে একমত, যে স্টোরকে একক একক হিসাবে ব্যবহার না করাই ভাল, যদি আপনি 100% নিশ্চিত না হন যে আপনি কেবল ক্লায়েন্ট-সাইড রেন্ডারিংয়ের জন্য ব্যবহার করবেন (অন্যথায় বাগগুলি খুঁজে পাওয়া শক্ত হবে)।

রিডুএক্সের ভার্বোসটি মোকাবেলা করার জন্য আমি সম্প্রতি একটি লাইব্রেরি তৈরি করেছি এবং আমার মনে হয় মিডলওয়্যারের মধ্যে সমস্ত কিছু রাখা ভাল ধারণা, তাই আপনারা নির্ভরতা ইঞ্জেকশন হিসাবে প্রত্যক্ষ করে তোলেন।

সুতরাং, আপনার উদাহরণটি দেখতে পাবেন:

import { createSyncTile } from 'redux-tiles';

const someTile = createSyncTile({
  type: ['some', 'tile'],
  fn: ({ params, selectors, getState }) => {
    return {
      data: params.data,
      items: selectors.another.tile(getState())
    };
  },
});

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


1

এটি সমাধানের বিকল্প উপায় উপস্থাপন করা। এটি আপনার প্রয়োগের উপর নির্ভর করে ড্যানের সমাধানের চেয়ে ভাল বা খারাপ হতে পারে।

ক্রিয়াকে 2 টি পৃথক ফাংশনে বিভক্ত করে আপনি হ্রাসকারীদের থেকে অ্যাকশনগুলিতে রাজ্যটি পেতে পারেন: প্রথমে ডেটা জিজ্ঞাসা করুন, ডেটাতে দ্বিতীয় কাজ করুন। আপনি এটি ব্যবহার করে করতে পারেন redux-loop

প্রথমে 'দয়া করে ডেটার জন্য জিজ্ঞাসা করুন'

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
    return {
        type: SOME_ACTION,
    }
}

রিডুসারে, জিজ্ঞাসাটি বিরত করুন এবং ব্যবহার করে দ্বিতীয় পর্যায়ে ক্রিয়ায় ডেটা সরবরাহ করুন redux-loop

import { loop, Cmd } from 'redux-loop';
const initialState = { data: '' }
export default (state=initialState, action) => {
    switch(action.type) {
        case SOME_ACTION: {
            return loop(state, Cmd.action(anotherAction(state.data))
        }
    }
}

হাতে থাকা ডেটা সহ, আপনি প্রথমে যা চান তা করুন

export const ANOTHER_ACTION = 'ANOTHER_ACTION';
export function anotherAction(data) {
    return {
        type: ANOTHER_ACTION,
        payload: data,
    }
}

আশা করি এটি কাউকে সাহায্য করবে।


0

আমি জানি যে আমি এখানে পার্টিতে দেরি করেছি, তবে আমি কর্মে রাষ্ট্র ব্যবহার করার নিজস্ব ইচ্ছা সম্পর্কে মতামতের জন্য এখানে এসেছি এবং তারপরে আমার নিজের তৈরি হয়েছিল, যখন আমি বুঝতে পারি যে আমি সঠিক আচরণটি কী বলে মনে করি।

এখানেই একজন নির্বাচক আমার কাছে সবচেয়ে বেশি অর্থবোধ করেন। আপনার উপাদান যা এই অনুরোধটি ইস্যু করে তা নির্বাচনের মাধ্যমে ইস্যু করার সময় এখনই বলা উচিত।

export const SOME_ACTION = 'SOME_ACTION';
export function someAction(items) {
  return (dispatch) => {
    dispatch(anotherAction(items));
  }
}

এটি অ্যাস্ট্রাকশনগুলি ফাঁস হওয়ার মতো মনে হতে পারে তবে আপনার উপাদানটির স্পষ্টভাবে একটি বার্তা প্রেরণ করা দরকার এবং বার্তাটির পেডে প্রাসঙ্গিক অবস্থা থাকা উচিত। দুর্ভাগ্যক্রমে আপনার প্রশ্নের কোন ठोस উদাহরণ নেই কারণ আমরা সেইভাবে নির্বাচক এবং ক্রিয়াগুলির একটি 'আরও ভাল মডেল' এর মাধ্যমে কাজ করতে পারি।


0

আমি আরও একটি বিকল্প প্রস্তাব দিতে চাই যা আমি সবচেয়ে পরিষ্কার খুঁজে পেয়েছি তবে এর জন্য প্রয়োজন react-reduxবা কিছু কিছু সিমুলার - এছাড়াও আমি কয়েকটি অন্যান্য অভিনব বৈশিষ্ট্যগুলি ব্যবহার করছি:

// actions.js
export const someAction = (items) => ({
    type: 'SOME_ACTION',
    payload: {items},
});
// Component.jsx
import {connect} from "react-redux";

const Component = ({boundSomeAction}) => (<div
    onClick={boundSomeAction}
/>);

const mapState = ({otherReducer: {items}}) => ({
    items,
});

const mapDispatch = (dispatch) => bindActionCreators({
    someAction,
}, dispatch);

const mergeProps = (mappedState, mappedDispatches) => {
    // you can only use what gets returned here, so you dont have access to `items` and 
    // `someAction` anymore
    return {
        boundSomeAction: () => mappedDispatches.someAction(mappedState.items),
    }
});

export const ConnectedComponent = connect(mapState, mapDispatch, mergeProps)(Component);
// (with  other mapped state or dispatches) Component.jsx
import {connect} from "react-redux";

const Component = ({boundSomeAction, otherAction, otherMappedState}) => (<div
    onClick={boundSomeAction}
    onSomeOtherEvent={otherAction}
>
    {JSON.stringify(otherMappedState)}
</div>);

const mapState = ({otherReducer: {items}, otherMappedState}) => ({
    items,
    otherMappedState,
});

const mapDispatch = (dispatch) => bindActionCreators({
    someAction,
    otherAction,
}, dispatch);

const mergeProps = (mappedState, mappedDispatches) => {
    const {items, ...remainingMappedState} = mappedState;
    const {someAction, ...remainingMappedDispatch} = mappedDispatch;
    // you can only use what gets returned here, so you dont have access to `items` and 
    // `someAction` anymore
    return {
        boundSomeAction: () => someAction(items),
        ...remainingMappedState,
        ...remainingMappedDispatch,
    }
});

export const ConnectedComponent = connect(mapState, mapDispatch, mergeProps)(Component);

আপনি এই পুনরায় ব্যবহার করতে চান, আপনি নির্দিষ্ট বের করে আনতে হবে mapState, mapDispatchএবং mergePropsফাংশন মধ্যে অন্যত্র পুনরায় ব্যবহার করার জন্য, কিন্তু এই অতি সুস্পষ্ট নির্ভরতা।

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