বাইন্ড অ্যাকশনক্রিটারগুলি কখন প্রতিক্রিয়া / রিডেক্সে ব্যবহৃত হবে?


95

Redux এর জন্য দস্তাবেজ bindActionCreators রাজ্যের যে:

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

কোথায় bindActionCreatorsব্যবহৃত / প্রয়োজন হবে একটি উদাহরণ হতে পারে?

কোন ধরণের উপাদান রেডাক্স সম্পর্কে সচেতন হবে না ?

উভয় বিকল্পের সুবিধা / অসুবিধাগুলি কী?

//actionCreator
import * as actionCreators from './actionCreators'

function mapStateToProps(state) {
  return {
    posts: state.posts,
    comments: state.comments
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(actionCreators, dispatch)
}

বনাম

function mapStateToProps(state) {
  return {
    posts: state.posts,
    comments: state.comments
  }
}

function mapDispatchToProps(dispatch) {
  return {
    someCallback: (postId, index) => {
      dispatch({
        type: 'REMOVE_COMMENT',
        postId,
        index
      })
    }
  }
}

উত্তর:


60

আমি মনে করি না যে সর্বাধিক জনপ্রিয় উত্তরটি আসলে প্রশ্নটিকে সম্বোধন করে।

নীচের সমস্ত উদাহরণ মূলত একই জিনিসটি করে এবং কোনও "প্রাক-বাঁধাই" ধারণাটি অনুসরণ করে।

// option 1
const mapDispatchToProps = (dispatch) => ({
  action: () => dispatch(action())
})


// option 2
const mapDispatchToProps = (dispatch) => ({
  action: bindActionCreators(action, dispatch)
})


// option 3
const mapDispatchToProps = {
  action: action
}

অপশন #3মাত্র বিকল্পের জন্য একটি সাঁটে লেখার হয় #1, তাই আসল প্রশ্নটি কেন একটি বিকল্প ব্যবহার করেন #1বিকল্প বনাম #2। আমি তাদের দু'জনকেই রিয়েড-রেডেক্স কোডবেসে ব্যবহৃত দেখেছি এবং আমি দেখতে পেয়েছি এটি বিভ্রান্তিকর।

আমি বিভ্রান্তির আসলে সব যে থেকে আসে মনে উদাহরণ মধ্যে react-reduxডক ব্যবহার bindActionCreatorsকিছুদিনের জন্য ডক bindActionCreators (প্রশ্ন নিজেই উদ্ধৃত হিসাবে) প্রতিক্রিয়া-redux সঙ্গে এটি ব্যবহার না করার বলছেন।

আমি অনুমান করি উত্তরটি কোডবেজে ধারাবাহিকতা রয়েছে, তবে যখনই প্রয়োজন হবে আমি ব্যক্তিগতভাবে প্রেরণে স্পষ্টভাবে মোড়ানোর ক্রিয়া পছন্দ করি ।


4
বিকল্পের #3জন্য বিকল্পটি #1কীভাবে সংক্ষিপ্ত হবে?
ogostos


@ আর্টেমবার্নটস্কি ধন্যবাদ সুতরাং, দেখা যাচ্ছে সেখানে 3 টি মামলা হয় আউট mapDispatchToProps: function, objectএবং হারিয়ে যাওয়া। প্রতিটি কেস কিভাবে পরিচালনা করবেন তা এখানে
ogostos

আমি এই উত্তর খুঁজছি। ধন্যবাদ
কিশান রাজদেব 16'19

আমি আসলে সেই নির্দিষ্ট ব্যবহারের ক্ষেত্রে এসেছি যা প্রতিক্রিয়া ডক্সের বিষয়ে এখন আলোচনা করা হয়েছে "কিছু ক্রিয়া নির্মাতাকে এমন একটি উপাদানে ফেলে যা যা রেডাক্স সম্পর্কে অবগত নয়" কারণ আমার আরও জটিল উপাদানগুলির সাথে সংযুক্ত এবং ওভারহেড যুক্ত করার একটি সহজ উপাদান রয়েছে এর reduxএবং connectএবং addDispatchToPropsসহজ কম্পোনেন্ট Overkill বলে মনে হয় যদি আমি শুধু একটা ঠেকনা নিচে পাস করতে পারেন। তবে যতদূর আমি সচেতন প্রায় সবগুলি ক্ষেত্রে mapDispatch#1#3
প্রপসগুলি

48

99% সময়, এটি প্যারামিটারের connect()অংশ হিসাবে প্রতিক্রিয়া-রেডাক্স ফাংশন সহ ব্যবহৃত হয় mapDispatchToProps। এটি আপনার সরবরাহ করা mapDispatchফাংশনের অভ্যন্তরে বা স্বয়ংক্রিয়ভাবে আপনি যদি শর্টহ্যান্ড সিন্ট্যাক্স অবজেক্টটি ব্যবহার করেন এবং অ্যাকশন স্রষ্টাকে পূর্ণ কোনও বস্তুটি পাস করেন তবে এটি স্বয়ংক্রিয়ভাবে ব্যবহার করা যেতে পারে connect

ধারণাটি হ'ল অ্যাকশন স্রষ্টাদের প্রাক-বাঁধাই করার মাধ্যমে আপনি যে উপাদানটি connect()প্রযুক্তিগতভাবে "জানেন না" এটির সাথে সংযুক্ত রয়েছে - এটি কেবল জানেন যে এটি চালানো দরকার this.props.someCallback()। অন্যদিকে, আপনি যদি অ্যাকশন স্রষ্টাদের বাঁধাই না করে এবং ডেকে থাকেন তবে this.props.dispatch(someActionCreator())এখন উপাদানটি "জানে" যে এটি সংযুক্ত কারণ এটি props.dispatchবিদ্যমান থাকার প্রত্যাশা করে।

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


4
তবে এটি 'মানচিত্রডিস্পচটপোপ্রোপস' এর সাথে সংযুক্ত, যা ভাল। মনে হচ্ছে এটি বাধ্যতামূলক অ্যাকশন নির্মাতারা আসলে একটি নেতিবাচক / অর্থহীন জিনিস কারণ আপনি ডিবাগিংয়ের মতো আরও অনেক জিনিসের মধ্যে ফাংশন সংজ্ঞা (টিএস বা ফ্লো) হারাবেন। আমার নতুন প্রকল্পগুলিতে আমি কখনই এটি ব্যবহার করি না এবং আজ পর্যন্ত আমার কোনও সমস্যা হয়নি। এছাড়াও সাগা ব্যবহার করে এবং স্থিতিশীল অবস্থা। এছাড়াও, আপনি যদি কেবল রিডুএক্স ফাংশনগুলি কল করছেন (আপনি দুর্দান্ত ক্লিক পেয়েছেন) তবে আমি এটি আরও পরিষ্কার বলেছি যে ক্রিয়া ক্রিয়েটরদের 'সংযুক্ত' করছি যা আমার মতে অগোছালো এবং অর্থহীন। আপনার স্মার্ট (সাধারণত পর্দার উপাদান) এখনও সংযোগ ব্যবহার করতে পারে, কেবল প্রপসগুলির জন্য।
অলিভার ডিকসন

19

আরও সম্পূর্ণ উদাহরণ, সংযোগ করতে ক্রিয়া স্রষ্টাদের পূর্ণ কোনও বস্তুটি পাস করুন:

import * as ProductActions from './ProductActions';

// component part
export function Product({ name, description }) {
    return <div>
        <button onClick={this.props.addProduct}>Add a product</button>
    </div>
}

// container part
function mapStateToProps(state) {
    return {...state};
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        ...ProductActions,
    }, dispatch);
}

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

এই উত্তরটি হওয়া উচিত
দ্বীন জন

16

আমি মূল প্রশ্নের উত্তর দেওয়ার চেষ্টা করব ...

স্মার্ট ও বোবা উপাদান

আপনার প্রথম প্রশ্নে আপনি মূলত জিজ্ঞাসা করছেন কেন bindActionCreatorsপ্রথম স্থানে প্রয়োজনীয় এবং কোন ধরণের উপাদানগুলি রেডাক্স সম্পর্কে সচেতন হওয়া উচিত নয়।

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

অন্যদিকে স্মার্ট উপাদানগুলি হ'ল এক ধরণের আঠালো, যা বোবা উপাদানগুলির জন্য ডেটা প্রস্তুত করে এবং পছন্দসই কোনও HTML উপস্থাপনা করে না।

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

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

আপনি এই ধারণাটি সম্পর্কে রেডাক্স ম্যানুয়ালটিতে এবং ড্যান আব্রামভের প্রেজেন্টেশনাল এবং কনটেইনার উপাদান নিবন্ধে আরও গভীরতার সাথে খুঁজে পেতে পারেন ।

যা উদাহরণ ভাল

দ্বিতীয় প্রশ্নটি প্রদত্ত উদাহরণগুলির সুবিধাগুলি / অসুবিধা সম্পর্কে ছিল।

ইন প্রথম উদাহরণ কর্ম স্রষ্টাদের একটি পৃথক মধ্যে সংজ্ঞায়িত করা হয় actionCreators, ফাইল / মডিউল যার মানে তারা অন্যত্র পুনঃব্যবহৃত করা যেতে পারে। ক্রিয়া সংজ্ঞায়নের এটি আদর্শ উপায় way আমি এতে আসলে কোনও অসুবিধা দেখতে পাচ্ছি না।

দ্বিতীয় উদাহরণ কর্ম স্রষ্টাদের ইনলাইন সংজ্ঞায়িত, যা একাধিক অসুবিধেও আছে:

  • ক্রিয়া স্রষ্টাদের পুনরায় ব্যবহার করা যাবে না (স্পষ্টতই)
  • জিনিসটি আরও ভার্জোজ, যা কম পাঠযোগ্য হিসাবে অনুবাদ করে
  • ক্রিয়া ধরণেরগুলি কঠোরভাবে কোড করা হয় - এগুলি constsপৃথক হিসাবে পৃথকভাবে সংজ্ঞায়িত করা ভাল , যাতে তাদের হ্রাসকারীদের ক্ষেত্রে উল্লেখ করা যায় - যা ভুল টাইপ করার সুযোগকে হ্রাস করবে
  • অ্যাকশন নির্মাতাদের ইনলাইন সংজ্ঞায়িত করা তাদের ব্যবহারের প্রস্তাবিত / প্রত্যাশিত পদ্ধতির বিরুদ্ধে - যা আপনার কোডটি ভাগ করে নেওয়ার পরিকল্পনা করার ক্ষেত্রে আপনার কোডটি সম্প্রদায়ের জন্য কিছুটা কম পঠনযোগ্য করে তুলবে

দ্বিতীয় উদাহরণটির প্রথমটির চেয়ে একটি সুবিধা রয়েছে - এটি লেখার পক্ষে দ্রুত! সুতরাং আপনার কোডের জন্য যদি আপনার আরও বৃহত্তর পরিকল্পনা না থাকে তবে এটি ঠিক আছে।

আমি আশা করি আমি কিছুটা পরিষ্কার করতে পেরেছি ...


2

এর একটি সম্ভাব্য ব্যবহার bindActionCreators()হ'ল একক প্রস্তাব হিসাবে একসাথে একাধিক ক্রিয়া "মানচিত্র" করা "

একটি সাধারণ প্রেরণ এটির মতো দেখাচ্ছে:

প্রপসগুলিতে কয়েকটি সাধারণ ব্যবহারকারীর ক্রিয়া মানচিত্র করুন।

const mapStateToProps = (state: IAppState) => {
  return {
    // map state here
  }
}
const mapDispatchToProps = (dispatch: Dispatch) => {
  return {
    userLogin: () => {
      dispatch(login());
    },
    userEditEmail: () => {
      dispatch(editEmail());
    },
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

বৃহত প্রকল্পগুলিতে প্রতিটি প্রেরণকে পৃথকভাবে ম্যাপিংয়ের ফলে স্বল্পতা বোধ করা যায়। আমরা যদি একে অপরের সাথে সম্পর্কিত ক্রুশগুলির একটি গুচ্ছ থাকে তবে আমরা এই ক্রিয়াগুলি একত্রিত করতে পারি । উদাহরণস্বরূপ একটি ব্যবহারকারীর অ্যাকশন ফাইল যা বিভিন্ন ধরণের ব্যবহারকারী সম্পর্কিত ক্রিয়া করে। প্রতিটি ক্রিয়াকে আলাদা প্রেরণ হিসাবে কল করার bindActionCreators()পরিবর্তে আমরা এর পরিবর্তে ব্যবহার করতে পারি dispatch

বাইন্ড অ্যাকশনক্রিটর () ব্যবহার করে একাধিক প্রেরণ

আপনার সমস্ত সম্পর্কিত ক্রিয়া আমদানি করুন। এগুলি সম্ভবত রিডুক্স স্টোরের একই ফাইলে রয়েছে

import * as allUserActions from "./store/actions/user";

এবং এখন প্রেরণ ব্যবহারের পরিবর্তে বাইন্ড অ্যাকশনক্রিটারগুলি ব্যবহার করুন ()

    const mapDispatchToProps = (dispatch: Dispatch) => {
      return {
           ...bindActionCreators(allUserActions, dispatch);
        },
      };
    };
    export default connect(mapStateToProps, mapDispatchToProps, 
    (stateProps, dispatchProps, ownProps) => {
      return {
        ...stateProps,
        userAction: dispatchProps
        ownProps,
      }
    })(MyComponent);

এখন আমি userActionআপনার উপাদানগুলির সমস্ত ক্রিয়াকলাপ কল করতে প্রপ ব্যবহার করতে পারি ।

আইই: userAction.login() userAction.editEmail() বা this.props.userAction.login() this.props.userAction.editEmail()

দ্রষ্টব্য: আপনাকে একটি বিন্যাসে bindActionCreators () মানচিত্র করতে হবে না। (অতিরিক্ত => {return {}}যে মানচিত্রগুলি userAction)। আপনি bindActionCreators()একক ফাইলের সমস্ত ক্রিয়া পৃথক প্রস হিসাবে মানচিত্র করতেও ব্যবহার করতে পারেন । তবে আমি মনে করি এটি করা বিভ্রান্তিকর হতে পারে। আমি প্রতিটি ক্রিয়া বা "অ্যাকশন গ্রুপ" এর একটি সুস্পষ্ট নাম দেওয়া পছন্দ করি। ownPropsএই "চাইল্ড প্রপস" কী বা তারা কোথা থেকে আসছে সে সম্পর্কে আমি আরও বর্ণনামূলক হতে চাই । Redux + প্রতিক্রিয়া ব্যবহার করার সময় এটি কিছুটা বিভ্রান্ত হতে পারে যেখানে সমস্ত প্রপস সরবরাহ করা হয় তাই আরও বর্ণনামূলক আরও ভাল।


2

bindActionCreatorsএটি ব্যবহার করে এটি একাধিক ক্রিয়া ফাংশনগুলি গোষ্ঠীভুক্ত করতে পারে এবং এটি এমন একটি উপাদানকে সরবরাহ করতে পারে যা Redux (বোবা উপাদান) সম্পর্কে অবগত নয় so

// actions.js

export const increment = () => ({
    type: 'INCREMENT'
})

export const decrement = () => ({
    type: 'DECREMENT'
})
// main.js
import { Component } from 'react'
import { bindActionCreators } from 'redux'
import * as Actions from './actions.js'
import Counter from './counter.js'

class Main extends Component {

  constructor(props) {
    super(props);
    const { dispatch } = props;
    this.boundActionCreators = bindActionCreators(Actions, dispatch)
  }

  render() {
    return (
      <Counter {...this.boundActionCreators} />
    )
  }
}
// counter.js
import { Component } from 'react'

export default Counter extends Component {
  render() {
    <div>
     <button onclick={() => this.props.increment()}
     <button onclick={() => this.props.decrement()}
    </div>
  }
}

প্রতিক্রিয়া-রিডেক্স থেকে ডিসপ্যাচ () ব্যবহার করার সময় এটি একই রকম মনে হয়
টনি জিন

1

আমি বাইন্ডএকশনক্রিটার সম্পর্কে আরও জানতে সন্ধান করছিলাম এবং আমি কীভাবে আমার প্রকল্পে প্রয়োগ করেছি।

// Actions.js
// Action Creator
const loginRequest = (username, password) => {
 return {
   type: 'LOGIN_REQUEST',
   username,
   password,
  }
}

const logoutRequest = () => {
 return {
   type: 'LOGOUT_REQUEST'
  }
}

export default { loginRequest, logoutRequest };

আপনার প্রতিক্রিয়া উপাদান

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ActionCreators from './actions'

class App extends Component {
  componentDidMount() {
   // now you can access your action creators from props.
    this.props.loginRequest('username', 'password');
  }

  render() {
    return null;
  }
}

const mapStateToProps = () => null;

const mapDispatchToProps = dispatch => ({ ...bindActionCreators(ActionCreators, dispatch) });

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

0

এক জন্য চমৎকার ব্যবহারের ক্ষেত্রে bindActionCreatorsসঙ্গে ইন্টিগ্রেশন জন্য redux-কাহিনী ব্যবহার redux-কাহিনী-রুটিন । উদাহরণ স্বরূপ:

// routines.js
import { createRoutine } from "redux-saga-routines";
export const fetchPosts = createRoutine("FETCH_POSTS");
// Posts.js
import React from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import { fetchPosts } from "routines";

class Posts extends React.Component {
  componentDidMount() {
    const { fetchPosts } = this.props;
    fetchPosts();
  }

  render() {
    const { posts } = this.props;
    return (
      <ul>
        {posts.map((post, i) => (
          <li key={i}>{post}</li>
        ))}
      </ul>
    );
  }
}

const mapStateToProps = ({ posts }) => ({ posts });
const mapDispatchToProps = dispatch => ({
  ...bindActionCreators({ fetchPosts }, dispatch)
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Posts);
// reducers.js
import { fetchPosts } from "routines";

const initialState = [];

export const posts = (state = initialState, { type, payload }) => {
  switch (type) {
    case fetchPosts.SUCCESS:
      return payload.data;
    default:
      return state;
  }
};
// api.js
import axios from "axios";

export const JSON_OPTS = { headers: { Accept: "application/json" } };
export const GET = (url, opts) =>
  axios.get(url, opts).then(({ data, headers }) => ({ data, headers }));
// sagas.js
import { GET, JSON_OPTS } from "api";
import { fetchPosts } from "routines";
import { call, put, takeLatest } from "redux-saga/effects";

export function* fetchPostsSaga() {
  try {
    yield put(fetchPosts.request());
    const { data } = yield call(GET, "/api/posts", JSON_OPTS);
    yield put(fetchPosts.success(data));
  } catch (error) {
    if (error.response) {
      const { status, data } = error.response;
      yield put(fetchPosts.failure({ status, data }));
    } else {
      yield put(fetchPosts.failure(error.message));
    }
  } finally {
    yield put(fetchPosts.fulfill());
  }
}

export function* fetchPostsRequestSaga() {
  yield takeLatest(fetchPosts.TRIGGER, fetchPostsSaga);
}

দ্রষ্টব্য যে এই প্যাটার্নটি প্রতিক্রিয়া হুক ব্যবহার করে প্রয়োগ করা যেতে পারে (প্রতিক্রিয়া 16.8)।


0
The only use case for bindActionCreators is when you want to pass some action creators down to a component that isn't aware of Redux, and you don't want to pass dispatch or the Redux store to it.

আপনি রিডেক্সের সাথে টাইপস্ক্রিপ্ট ব্যবহার করলে এটি খুব সহায়ক helpful


-1

ডক্স বক্তব্য খুব স্পষ্ট:

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

এটি স্পষ্টভাবে একটি ব্যবহারের কেস যা নিম্নলিখিত এবং শুধুমাত্র একটি শর্তে উদ্ভূত হতে পারে:

বলি, আমাদের A এবং B উপাদান রয়েছে:

// A use connect and updates the redux store
const A = props => {}
export default connect()(A)

// B doesn't use connect therefore it does not know about the redux store.
const B = props => {}
export default B

রিডাক্ট-রিডেক্স ইনজেকশন: (এ)

const boundActionCreators = bindActionCreators(SomeActionCreator, dispatch)
// myActionCreatorMethod,
// myActionCreatorMethod2,
// myActionCreatorMethod3,

// when we want to dispatch
const action = SomeActionCreator.myActionCreatorMethod('My updates')
dispatch(action)

রিঅ্যাক্ট-রিডেক্স দ্বারা সংক্রামিত: (খ)

const { myActionCreatorMethod } = props
<B myActionCreatorMethod={myActionCreatorMethod} {...boundActionCreators} />

নীচের দিকে লক্ষ্য করা যায়?

  • আমরা কম্পোনেন্ট এ এর ​​মাধ্যমে রিডাক্স স্টোর আপডেট করেছি যখন আমরা বি বি উপাদানগুলির রেডেক্স স্টোর সম্পর্কে অজানা ছিলাম il

  • আমরা উপাদান A তে আপডেট করছি না ঠিক আমার অর্থটি কী তা জানতে আপনি এই পোস্টটি অন্বেষণ করতে পারেন । আমি আশা করি আপনার একটি ধারণা থাকবে।


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