0

I have a context object with an object holding all the information I need for a specific section of my application. The object contains some arrays.

Data

{
   groupname: 'a',
   members: {
     regular: [
         { id: 1, name: 'x' },
         { id: 2, name: 'y' },
     ],
     premium: []
  }
}

I have a form where I can create a new member. Once the member is created I have a function inside a hook where I call the addMember function to add this newly created member.

function useGroup({ initialGroup: GroupType }: Props) {
    const [group, setGroup] = useState<GroupType>(initialGroup)

    const addMember = (member) => {
       group.members.regular = [...group.members.regular, member]
       setGroup(group)
    }

    return {
       group,
       addMember
    }
}

I can use a console log and see this working effectively, however this is not being reflected in my UI. I can see the items when I refresh the page. This is telling me that the UI isnt 'refreshing' when I push the extra item inside my state object.

I feel as if this is because it is a nested array inside of an object. Should I split the members out into there own 'useState' arrays or is there something I am missing to have my UI reflect this being added?

2 Answers 2

1

You're changing the state variable directly.

Try the following approach.

function useGroup({ initialGroup: GroupType }: Props) {
    const [group, setGroup] = useState<GroupType>(initialGroup)

    const addMember = (member) => {
       setGroup(state => {
          const _state = {...state};
                _state.members.regular.push(member);

          return _state;
       });
    }

    return {
       group,
       addMember
    }
}

Update:
You can also use useCallback to prevent the addMember function from being created over an over.

const addMember = useCallback((member) => {
  setGroup(state => {
    const _state = {...state};
          _state.members.regular.push(member);

    return _state;
  });
}, []);
Sign up to request clarification or add additional context in comments.

Comments

1

You are actually changing a state variable incorrectly.
You can try modifying the addMember function as follows:

const addMember = (member) => {
        setGroup({...group,members:{
                regular: [...group.members.regular, member]
            }})
}

EDIT: on onClick (as an example) you must execute the function, not call it in order to work.
eg: <button onClick={addMember({...})}>Example</button>.
NOT <button onClick={() => addMember({...})}>Example</button>

1 Comment

If you have onClick={addMember({ ... })} The function is immediately fired on render not on click. This is because you are calling the function instead of passing it to the onclick handler so your edit is incorrect

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.