হ'ল রিডেক্স ব্যবহার করে কোনও আইটেম মোছার সঠিক উপায়?


116

আমি জানি যে আমি ইনপুটটি পরিবর্তন করতে পারব না এবং এটিকে রূপান্তর করতে অবজেক্টটির ক্লোন করা উচিত। আমি একটি রেডুয়াক্স স্টার্টার প্রকল্পে ব্যবহৃত কনভেনশনটি অনুসরণ করছিলাম যা ব্যবহৃত হয়েছিল:

ADD_ITEM: (state, action) => ({
  ...state,
  items: [...state.items, action.payload.value],
  lastUpdated: action.payload.date
})

আইটেম যুক্ত করার জন্য - আমি অ্যারেতে আইটেম সংযোজন করতে স্প্রেডের ব্যবহার পাই।

মুছে ফেলার জন্য আমি ব্যবহার করেছি:

DELETE_ITEM: (state, action) => ({
  ...state,
  items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
  lastUpdated: Date.now() 
})

তবে এটি ইনপুট স্থিতি অবজেক্টটিকে রূপান্তর করছে - আমি কোনও নতুন অবজেক্ট ফিরিয়ে দিলেও কি এটি নিষিদ্ধ?


1
দ্রুত প্রশ্ন. স্প্লাইস আপনি মুছে ফেলা আইটেম ফেরত। এটা কি আপনার উদ্দেশ্য? যদি না হয় তবে আপনার স্লাইস ব্যবহার করা উচিত, যা কোনও মিউটেশন আইন দ্বারাও মেনে চলে।
এম0meni

ভাল এই উদাহরণে আমি অ্যারের দুটি বিভাগকে একত্রে একটি নতুন অ্যারেতে বিভক্ত করছি - আমি যে আইটেমটি বাম বাদ দিতে চাইছিলাম তা দিয়ে। স্লাইস কি সরানো আইটেমটি ঠিক ফেরত দেয়? শুধুমাত্র এটি মূল অ্যারেটি পরিবর্তন না করেই এমন করে তোলে যাতে আরও ভাল পদ্ধতির হতে পারে?
সিটাইট

@ এআর 7 আপনার পরামর্শ অনুসারে: items: [...state.items.slice(0, action.payload.value), ...state.items.slice(action.payload.value + 1 )]স্প্লাইসের পরিবর্তে এখন স্লাইস ব্যবহার করুন যাতে ইনপুটটি পরিবর্তন না করা যায় - এই উপায় কি এই উপায় বা আরও সংক্ষিপ্ত উপায় আছে?
সিউরাইট

উত্তর:


207

না your

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

পরিবর্তে, অপরিবর্তনীয় পদ্ধতি ব্যবহার করুন। সর্বদা ব্যবহার Array#sliceএবং কখনই না Array#splice

আমি আপনার কোড থেকে ধরে নিই যে action.payloadসরানো আইটেমের সূচি index আরও ভাল উপায় নিম্নলিখিত হিসাবে হবে:

items: [
    ...state.items.slice(0, action.payload),
    ...state.items.slice(action.payload + 1)
],

এটি কার্যকর হয় না যদি আমরা অ্যারেতে শেষ উপাদানটি নিয়ে কাজ করি, ...দ্বিতীয় বিবৃতিতেও ব্যবহার করা আপনার রাজ্যের সামগ্রীর দ্বিগুণ হয়ে যাবে
থেইনর

4
দয়া করে এটি প্রমাণ করুন একটি jsfiddle / কোডেপেন উদাহরণ দিয়ে। স্নিপেটে arr.slice(arr.length)সর্বদা একটি খালি অ্যারে তৈরি করা উচিত যা বিষয়বস্তুই হোক না কেন arr
ডেভিড এল ওয়ালশ

1
@ ডেভিড-এল-ওয়ালশ এই বিভ্রান্তির জন্য দুঃখিত, এই উদাহরণটি পরীক্ষা করার সময় আমার অবশ্যই একটি টাইপো বা কিছু তৈরি করা উচিত। এটি আশ্চর্য কাজ করে। আমার একমাত্র প্রশ্ন: ...দ্বিতীয় অংশে স্প্রেড অপারেটরের প্রয়োজন কেন...state.items.slice(action.payload + 1)
থেইনর

5
Array#sliceএকটি অ্যারে প্রদান করে। দুটি স্লাইস একক অ্যারেতে একত্রিত করতে, আমি স্প্রেড অপারেটরটি ব্যবহার করেছি। এটি ছাড়া আপনার অ্যারে একটি অ্যারে থাকবে।
ডেভিড এল ওয়ালশ

4
এটা বোধগম্য. পরিষ্কার করার জন্য আপনাকে অনেক ধন্যবাদ (এবং প্রথমে বিভ্রান্তির জন্য দুঃখিত)।
Thaenor

149

আপনি মূল স্থানে পরিবর্তন না করে অ্যারে থেকে একটি নির্দিষ্ট উপাদান অপসারণ করতে অ্যারে ফিল্টার পদ্ধতিটি ব্যবহার করতে পারেন।

return state.filter(element => element !== action.payload);

আপনার কোডের প্রসঙ্গে এটি দেখতে এমন কিছু দেখাচ্ছে:

DELETE_ITEM: (state, action) => ({
  ...state,
  items: state.items.filter(item => item !== action.payload),
  lastUpdated: Date.now() 
})

1
ফিল্টার একটি নতুন অ্যারে উত্পাদন করে?
চেনোপ

6
@ চেঞ্জ হ্যাঁ, অ্যারে.ফিল্টার পদ্ধতিটি একটি নতুন অ্যারে প্রদান করে। বিকাশকারী.মোজিলা.আর.ইন-
স্টেপ এম

4
নোট করুন যদি এখানে সদৃশ থাকে তবে এটি তাদের সমস্ত মুছে ফেলবে। নির্দিষ্ট সূচকটি অপসারণ করতে ফিল্টার ব্যবহার করতে, আপনি যেমনarr.filter((val, i) => i !== action.payload )
erich2k8

21

ES6 Array.prototype.filterপদ্ধতি মানদণ্ডের সাথে মেলে এমন আইটেমগুলির সাথে একটি নতুন অ্যারে প্রদান করে। সুতরাং, মূল প্রশ্নের প্রসঙ্গে, এটি হবে:

DELETE_ITEM: (state, action) => ({
  ...state,
  items: state.items.filter(item => action.payload !== item),
  lastUpdated: Date.now() 
})

.filter()কোনও ES2015 পদ্ধতি নয়, তবে পূর্ববর্তী সংস্করণ ES5 এ যুক্ত করা হয়েছে।
মোরক্রো

7

অবজেক্টস সহ অ্যারের জন্য অপরিবর্তনীয় "মুছে ফেলা" হ্রাসকারকের আরও একটি প্রকরণ:

const index = state.map(item => item.name).indexOf(action.name);
const stateTemp = [
  ...state.slice(0, index),
  ...state.slice(index + 1)
];
return stateTemp;

0

সুবর্ণ নিয়মটি হ'ল আমরা কোনও রূপান্তরিত রাষ্ট্র ফিরিয়ে দিই না, বরং একটি নতুন রাষ্ট্র ফিরিয়ে দেব। আপনার ক্রিয়াটির ধরণের উপর নির্ভর করে আপনার সরকারী বৃক্ষটি যখন হ্রাসকারকে আঘাত করে তখন আপনাকে বিভিন্ন রূপে আপডেট করতে হবে।

এই দৃশ্যে আমরা রাষ্ট্রীয় সম্পত্তি থেকে কোনও আইটেম সরানোর চেষ্টা করছি।

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

নেস্টেড বস্তুটি কীভাবে মুছবেন তার উদাহরণ এখানে রয়েছে:

// ducks/outfits (Parent)

// types
export const NAME = `@outfitsData`;
export const REMOVE_FILTER = `${NAME}/REMOVE_FILTER`;

// initialization
const initialState = {
  isInitiallyLoaded: false,
  outfits: ['Outfit.1', 'Outfit.2'],
  filters: {
    brand: [],
    colour: [],
  },
  error: '',
};

// action creators
export function removeFilter({ field, index }) {
  return {
    type: REMOVE_FILTER,
    field,
    index,
  };
}

export default function reducer(state = initialState, action = {}) {
  sswitch (action.type) {  
  case REMOVE_FILTER:
  return {
    ...state,
    filters: {
    ...state.filters,
       [action.field]: [...state.filters[action.field]]
       .filter((x, index) => index !== action.index)
    },
  };
  default:
     return state;
  }
}

এটি আরও ভালভাবে বুঝতে, এই নিবন্ধটি পরীক্ষা করে দেখুন: https://medium.com/better-programming/deleting-an-item-in-a-nested-redux-state-3de0cb3943da

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