क्या मामलों में उपयोगकर्ता में प्रसार ऑपरेटर की अनदेखी की वजह से निर्माता कीड़े हो जाएगा?

Nov 25 2020

अधिकांश useReducerउदाहरणों में मैंने देखा, राज्यों को संरक्षित करने के लिए प्रसार ऑपरेटर का उपयोग किया गया है। हालांकि, मेरी सभी प्रथाओं में, इसे अनदेखा करने से कभी कोई समस्या नहीं हुई। ऐसा लगता है कि रेड्यूसर फैल ऑपरेटर के बिना राज्य को संरक्षित करने में सक्षम है। निम्नलिखित उदाहरण की जाँच करें:

const initialState = {
    color: 'black',
    bgColor: 'white'
}

const reducer = (state, action) => {
    switch (action.type) {
        case 'dawn':
            return {
                ...state,
                color: 'white',
                bgColor: 'purple'
            }
        case 'reset':
            return initialState
        default:
            return {
                state
            }
    }
}

const UseReducerColorSetter = () => {
    const [state, dispatch] = useReducer(reducer, initialState);
    const { color, bgColor } = state;
    return (
        <>
            <div style={{ color: `${color}`, backgroundColor: `${bgColor}` }} className='card'>
                Hello
            </div>
            <button onClick={() => dispatch({ type: 'dawn' })}>Dawn mode</button>
            <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
        </>
    )
}

इस उदाहरण में, हटाने से ...stateकोई समस्या नहीं होती है, कोई राज्य परिवर्तन नहीं होता है, कोई कंसोल त्रुटि नहीं होती है, आदि।

इस सवाल में मैंने पूछा: क्या यह आवश्यक है कि उपयोग किए गए ऑपरेटर में स्प्रैड ऑपरेटर का उपयोग किया जाए , फैले हुए ऑपरेटर की अनदेखी करने से समस्याएँ पैदा हुईं useState, लेकिन फिर भी इन मुद्दों के साथ useReducer

क्या कोई मुझे प्रसार ऑपरेटर की अनदेखी करने के कुछ उदाहरण प्रदान कर सकता है, जिसमें समस्याएँ पैदा हो रही हैं useReducer? क्या कोई रिड्यूसर राज्य को संरक्षित कर सकता है?

जवाब

1 BrianThompson Nov 24 2020 at 23:53

यहाँ एक चल उदाहरण दिखा रहा है कि यदि आप एक reducer में सभी ऑब्जेक्ट गुणों को प्रतिस्थापित नहीं करते हैं, तो वे खो जाएंगे। मुद्रित परिणाम के साथ कंसोल लॉग किए गए प्रारंभिक मानों की तुलना करें।

const initialState = {
  color: "black",
  bgColor: "white"
};

const reducer = (state, action) => {
  switch (action.type) {
    case "dawn":
      return {
        bgColor: "purple" // Updated to only return one property to illustrate the problem
      };
    case "reset":
      return initialState;
    default:
      return {
        state
      };
  }
};

function App() {
  const [state, dispatch] = React.useReducer(reducer, initialState);

  React.useEffect(() => {
    console.log("Initial: ", state)
    dispatch({ type: "dawn" });
  }, []);

  return <div>{JSON.stringify(state)}</div>;
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Reducer फ़ंक्शन के हस्ताक्षर पर ध्यान दें (state, action) => newState। यह फ़ंक्शन नया राज्य लौटाता है। तो आप returnreducer से जो कुछ भी अपने संपूर्णता में नए राज्य मूल्य है। इसका मतलब है कि रूट स्टेट ऑब्जेक्ट को फैलाने के बिना, आप किसी भी ऐसे मान को खो देंगे जो नई ऑब्जेक्ट में स्पष्ट रूप से सेट नहीं है।

सीधे आपके प्रश्न का उत्तर देने के लिए, reducer के अपडेट पर पिछली स्थिति को न फैलाने पर कीड़े पैदा हो जाएंगे जब आपका राज्य एक सरणी या ऑब्जेक्ट होगा, और आप उस संरचना में प्रत्येक मान को मैन्युअल रूप से प्रतिस्थापित नहीं करते हैं।

यदि आप हमेशा प्रत्येक ऑब्जेक्ट प्रॉपर्टी सेट करते हैं या पिछली स्थिति वापस करते हैं, तो आप बग का सामना कभी नहीं करेंगे। यह वह परिदृश्य है जिसे आपने प्रश्न में दिया है, और यही कारण है कि यह अनावश्यक लगता है।

SergioVargas Nov 24 2020 at 23:28

आपके विशिष्ट मामले में, यह उन मुद्दों को प्रभावित या प्रभावित नहीं करेगा, क्योंकि आप राज्य के मूल्यों (रंग और bgColor) को बदल रहे हैं, अगर आपके पास एक ऐसा मामला है जो केवल उदाहरण के लिए रंग बदलता है, तो प्रसार ऑपरेटर की अनदेखी राज्य को bgColor मान के बिना छोड़ देगा, यह अगर आपके ऐप में हर समय bCColor होने की उम्मीद है तो समस्याएँ हो सकती हैं।

 case 'blue':
            return {
                color: 'blue',
            }