How can I use Redux to only update one instance of a component?

dustin

I'm trying to use Redux to update my Card Component to disable and change colors on click. Redux dispatches the action fine, but it updates all Cards not just the one that was clicked. Each Card has an object associated with it that hold the word and a value. The value is the className I want to use to change the color when clicked

Component

const Card = ({ wordObj, updateClass, isDisabled, cardClass }) => {
    
    const showColor = (e) => {
        updateClass(wordObj);
        console.log(cardClass)
    };
    return (
        <button
            onClick={(e) => showColor()}
            disabled={isDisabled}
            className={cardClass}>
            {wordObj.word}
        </button>
    );
};


const mapStateToProps = (state) => ({
    cardClass: state.game.cardClass,
});
export default connect(mapStateToProps, { updateClass })(Card);

Action

export const updateClass = (obj) => (dispatch) => {
    console.log(obj)
    dispatch({
        type: UPDATE_CARD,
        payload: obj,
    });
};

Reducer

const initialState = {
    words: [],
    cardClass: 'card',
    isDisabled: false,
};

export default function (state = initialState, action) {
    const { type, payload } = action;
    switch (type) {
        case SET_WORDS: {
            return {
                ...state,
                words: payload,
            };
        }   

        case UPDATE_CARD:
            return {
                ...state,
                isDisabled: true,
                cardClass: ['card', payload.value].join(' '),
            };

        default:
            return state;
    }
}```
Victor_Maciel

All of your card components are consuming the same cardClass field in the state. When you modify it in this line:

cardClass: ['card', payload.value].join(' ')

All cards that are consuming this field have their classes updated. The same occurs to the isDisable field.

You need to create one object for each card in your state. Here is my implementation (was not tested):

const initialState = {
    cards: []
};

export default function (state = initialState, action) {
    const { type, payload } = action;
    switch (type) {
        // create a card object for each word
        case SET_WORDS: {
            return {
                ...state,
                cards: payload.map(word => {
                    return { word: word, cardClass: "card", isDisabled: false }
                })
            };
        }   

        case UPDATE_CARD:
            // here i'm using the wordObj.word passed as payload
            // to identify the card (i recommend to use an id field) 
            const cardIndex = state.cards.findIndex(card => card.word === payload.word);
            // get the current card
            const card = state.cards[cardIndex];
            // create an updated card object obeying the immutability principle
            const updatedCard = { ...card, isDisabled: true, cardClass: ['card', payload.value].join(' '), }
            return {
                ...state,
               cards: [
                   ...state.cards.slice(0, cardIndex), // cards before
                   updatedCard,
                   ...state.cards.slice(cardIndex + 1) // cards after
               ]
                
            };

        default:
            return state;
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Why can i have only one instance of Calendar object

How do I only update one value of my reducer in Redux?

How can I use redux persist for only one reducer not for navigation reducer in my react native application?

when use redux, can I call api in container component?

Angular2 How can i Use One Component function In Another Component

How to update only one value in nested array of Redux state?

Can I use CRUDRepository to update an entity holding only one field?

Using Angular, how Can I add dynamically a component on click ? (Not only one)

How can I filter a sheet to show only one instance of a particular substring?

Django: How can I use templating to add a header to each HTML page, and only update one central file?

How can i use * in css to select all but only one

How can i only re-render the new child component when mapping an array from Redux state?

How can I query only one instance of a label?

How can I update a hook from one component and have it update another component as a result?

How can i use spread only one time?

How can I enforce a rule where only one instance of a class can have a certain parameter set to true?

How can I prevent to run same batch file twice to allow only one instance?

How can I Destroy AUI-Form-Validator so I only have one instance

Can I use HOC to wrap component with graphql and redux

How can I use Knockoutjs "with" context and update only one bound value?

React Native / Redux - Can only update a mounted or mounting component

How can I use only one section for my home page

How do i can test component in redux

How to use only one named slot in the component?

How can I make only one instance of an application receive each AMQP topic message (consumer group behaviour)

A component can only have one instance-level <script> element

In Django, how can I have a function where I can only update the value instead of creating a new instance of it?

How can I issue a warning for only one instance of a module?

How can I ensure that only one instance of an Azure Synapse Pipeline modifies a lake database at the same time?

TOP Ranking

HotTag

Archive