Reputation: 143
I'm using NativeBase in a React Native app. I'm trying to show a Toast component based on an error that is set in an redux action because it happens via a call to the API.
It will show now, but currently I get the warning message:
Warning: Cannot update during an existing state transition (such as within
render
or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved tocomponentWillMount
.
I'm not sure how I could bind this or what I could do to solve the warning.
Render Method
render() {
return (
<View>
{this.renderError()}
{this.renderForm()}
</View>
);
}
Render Error Method
renderError() {
if (this.props.error.type === 'server') {
return (
Toast.show({
text: this.props.error.message,
buttonText: 'Okay',
duration: 5000,
type: 'danger'
})
);
}
}
Versions
React Native: 0.55.4
Native Base: 2.4.5
Edit: Adding an example for clarity
I need to show a Toast based on the response from the server. For example, if the username and password don't match an account, I need to render the Toast.
Solution:
I ended up creating a ToastService:
import { Toast } from 'native-base';
function showToast(message) {
return (
Toast.show({
text: message,
buttonText: 'Okay',
duration: 5000,
type: 'danger'
})
);
}
export default {
showToast
};
and now in my action I can just call:
ToastService.showToast(data);
Upvotes: 6
Views: 9918
Reputation: 1854
Like Dwayne says above, you need to use useEffect so that Toast is called before the render cycle. You can wrap this is a component like so:
const ErrorToast: React.FC = () => {
const {state} = useCollections();
useEffect(() => {
if(state.errored) {
Toast.show({
text: 'Oops. There has been an error',
duration: 2000
});
}
});
return null;
}
And then simply include it as <ErrorToast />
Upvotes: 0
Reputation: 343
I solved this issue by using React Hooks.
() => {
useEffect(() => {
if(error) {
Toast.show({
text: this.props.error.message,
buttonText: 'Okay',
duration: 5000,
type: 'danger'
})
}
})
return (
<View>
{this.renderForm()}
</View>
);
}
Upvotes: 3
Reputation: 5929
You can create a function and call this one outside. But make sure your app is wrap with the Root component of native-base. No need to return a component like you do. Calling this function gonna show the toastr and now you have the freedom to call from anywhere. But make sure Root component wrap your app.
import { Toast } from 'native-base';
export const toastr = {
showToast: (message, duration = 2500) => {
Toast.show({
text: message,
duration,
position: 'bottom',
textStyle: { textAlign: 'center' },
buttonText: 'Okay',
});
},
};
Now inside your action you can call the toastr function
toastr.showToast('Verication code send to your phone.');
Or in redux actions
const signup = values => dispatch => {
try {
// your logic here
} catch (error) {
toastr.showToast(error.message)
}
}
Upvotes: 5
Reputation: 1155
Check React Native Seed for this implementation https://reactnativeseed.com/
Upvotes: 1