0

How can I use the mapdispatchtoprops function correctly to dispatch to reducer? First, I get data from the server and want to send this data to the reducer. firebaseChatData function cannot be transferred to the mapdispatchtoprops because it is inside the component

Messages.js

const MessageUiBody = ( { messages, loading } ) => {

    const userData = JSON.parse(localStorage.getItem("user-data"));

    useEffect( () => {

        const firebaseChatData = () => (dispatch) => {
            firebaseDB.ref().child(API.firebaseEnv + "/messages/messageItem" + userData.account_id)
                .on("value", snap => {
                    const firebaseChat = snap.val();
                    // console.log(firebaseChat)
                    dispatch(firebaseChatAction(firebaseChat))
                });
        };
    }, []);


  return(

      <div> // code </div>
  );
};


//Action
const firebaseChatAction = (firebaseChat) => ({
    type: 'FIREBASE_MESSAGE',
    firebaseChat
});

const mapDispatchToProps = (dispatch) => {
    return {
        data : () => {
            dispatch(firebaseChatData())
        }
    }
};


export default connect(null, mapDispatchToProps)(MessageUiBody)

Reducer

export default function messages ( state = [], action = {}) {
    switch (action.type) {
        case 'FIREBASE_MESSAGE' :
            state.data.messages.push(action.firebaseChat);
            return {
                ...state
            };
        default:
            return state
    }
}

1 Answer 1

1

You'll have to change your code, because you're defining data as the prop function that will dispatch your action:

const mapDispatchToProps = dispatch => {
 return {
  data: (result) => dispatch(firebaseChatAction(result)),
 }
}

After that change the line after the console log in your promise and use the data prop that you defined in your mapDispatch function:

const MessageUiBody = ( { data, messages, loading } ) => {

const userData = JSON.parse(localStorage.getItem("user-data"));

useEffect( () => {

    const firebaseChatData = () => (dispatch) => {
        firebaseDB.ref().child(API.firebaseEnv + "/messages/messageItem" + userData.account_id)
            .on("value", snap => {
                const firebaseChat = snap.val();
                // here you call the data that will dispatch the firebaseChatAction
                data(firebaseChat)
            });
    };
}, []);


return(

  <div> // code </div>
);
};

Also is worth to notice that you don't have to push items in your state, you can't mutate the current state, so always try to generate new items instead of modifying the existing one, something like this:

export default function messages ( state = [], action = {}) {
 switch (action.type) {
    case 'FIREBASE_MESSAGE' :
        return {
            ...state,
            data: {
             ...state.data,
             messages: [...state.data.messages, action.firebaseChat]
            }
        };
    default:
        return state
 }
}

With the spread operator you are returning a new array that contains the original state.data.messages array and will add the firebaseChat item as well.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for feedback, i copy this code, but nothing actions, state is empty
if you do a log after the case of 'FIREBASE_MESSAGE' what do you get? it is still empty?
i checked whit redux dev tools, not any anctions
Thank for code, it's work, problem is timeout from server, i solved with setTimeout

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.