1

I have a component that consists of photo grid where users can click on a cell to upload images from the camera roll. The component state is an object with a series of key value pairs, the key being the index and the value is itself an object with an image property. The state is being updated correctly upon photo upload and deletion, it's just when I call dispatch that I get an error.

Similar questions have involved people calling dispatch within async function or using await but I make no declaration here.

This has been irritating me for the last day and I feel like I'm missing something really obvious so I appreciate any help.

const PhotoUpload = ({ navigation }) => {


    const [photos, setPhotos] = useState(
        {'0' : {image: null},
         '1' : {image: null},
         '2' : {image: null},
         '3' : {image: null},
         '4' : {image: null},
         '5' : {image: null}}
     )

    const dispatch = useDispatch();
    dispatch(setPhotos(photos)); // Error: Actions must be plain objects. Use custom middleware for async actions.


    ...

    return (
        <>
            <SortableGrid >
            {
                Object.keys(photos).map((key) =>  
                // image is not showing
                <View key={ key } fixed={photos[key].image === null ? true : false} onTap={() => this.pickSingle(true, false, key)}  style={ styles.itemContainer } >
                    <Image defaultSource={ require('./default-avatar.png') } source={ getPhoto(key) } style={ styles.itemImage }  />
                    { photos[key].image != null 
                        ? <TouchableOpacity onPress={() => deletePhoto(key)} style={styles.deleteButton} >
                            <Icon name={"ios-remove"}  size={20} color="#ff0000" />
                          </TouchableOpacity>
                        : null
                    }
                </View>

                )
            }
            </SortableGrid>
        </>
    )

This is my reducer:

const INITIAL_STATE = {
  user: {
    name: "",
    gender: "",
    birthdate: "",
    photos: {},
  }
}


const userReducer = (state = INITIAL_STATE, action) => {
    switch (action.type) {
      case 'SETPHOTOS':
          return {
            // likely incorrect logic here
            ...state, 
            user: {
              ...state.user,
              photos : state.user.photos.concat(action.payload)
            }
          }
      default:
        return state
    }
  };

And the Action:

export const setPhotos = (receivedPhotos) => {
    console.log(receivedPhotos)
    return{
        type: 'SETPHOTOS',
        payload: receivedPhotos
    };
}

1 Answer 1

1

It might be a variable name conflict? From what I can see you've used the name setPhotos for your action AND to set your local component state.

When you call dispatch(setPhotos(photos)) it is trying to dispatch the local setPhotos, not your redux action, hence the error.

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

2 Comments

That was it, kicking myself now. Thanks James!
No problem. It's easy to to lose sight of things like that! :) Would you mind marking this as the accepted answer?

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.