Reputation: 285
Maybe that's a stupid question, but I have a problem. My state looks like this:
const initialState: PhotoState = {
photos: [],
};
The reducer code looks like this:
const initialState: PhotoState = {
photos: [],
};
export default function photoReducer(state = initialState, action: PhotoActionTypes): PhotoState {
switch (action.type) {
case SET_PHOTOS:
const photos: any[] = action.payload;
return {...state, photos};
}
return state;
};
I get photos from API and then set them this way:
export function setPhotos(payload: any[]): PhotoActionTypes {
return {type: SET_PHOTOS, payload};
}
export function getPhotos() {
return (dispatch: Dispatch<PhotoActionTypes>, getState: () => RootState): void => {
const profile_id = getState().auth.profile_id;
ax().post('pictures/api/pictures/list', {profile_id}).then((response) => {
const photos: any[] = response.data.pictures || [];
dispatch(setPhotos(photos));
})
}
}
Also I have an action that sends a new photo to the server and saves it in history. Then I get photos in component:
useEffect(() => {
dispatch(getPhotos());
}, []);
const handleSendPhoto = (): void => {
dispatch(sendPhoto(image?.base64));
dispatch(getPhotos());
}
The whole component:
const PhotoScreen = () => {
const [photoFlag, setPhotoFlag] = useState(false);
const [image, setImage] = useState<TakePictureResponse | null>(null);
const [height, setHeight] = useState(0);
const width = Dimensions.get('screen').width / 5;
const dispatch = useDispatch();
const handleSendPhoto = (): void => {
dispatch(sendPhoto(image?.base64, location));
dispatch(getPhotos());
}
const PhotoView = () => (
<View>
<FastImage
style={{width: width, height: height}}
source={{
uri: `data:image/jpeg;base64, ${image?.base64}`,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.contain}
onLoad={evt => {
setHeight(evt.nativeEvent.height / evt.nativeEvent.width * width)
}}
/>
<Button
mode="contained"
onPress={handleSendPhoto}
disabled={!image}
color={constants.buttonColor}>
Add photo
</Button>
</View>
);
return (
<SafeAreaView style={{...mainStyles.screen, ...styles.container}}>
<StatusBarDark />
{!photoFlag && (<View>
<Button
mode="contained"
onPress={() => setPhotoFlag(true)}
color={constants.buttonColor}>
Make photo
</Button>
</View>)}
{photoFlag && <CameraComponent setImage={setImage} setPhotoFlag={setPhotoFlag}/>}
{image !== null && <PhotoView />}
</SafeAreaView>
);
};
export default PhotoScreen;
But state updates only from the second time. I press the button 'Add photo', photo appends to history, but doesn't shows up in it. Then I press the button again, and previous photo shows up in history, but current photo doesn't.
How can I fix it?
UPD: Problem was solved. The question may be closed.
Upvotes: 0
Views: 314
Reputation: 1036
You shouldn't do this, because both calls will be send at the same time:
const handleSendPhoto = (): void => {
dispatch(sendPhoto(image?.base64));
dispatch(getPhotos()); // this will be called before the upload is finished. so the old data will be returned.
}
you may need to use redux-thrunk (https://github.com/reduxjs/redux-thunk) like this:
const handleSendPhoto = (): void => {
dispatch(sendPhoto(image?.base64)).then(() => dispatch(getPhotos()));
}
Upvotes: 2