-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add onLoad and onError callbacks #192
Conversation
bildja
commented
Apr 23, 2018
- I need to show and to do something once image has been loaded and therefore I need a callback for it.
- I need to send a message to error logger, when image couldn't load.
Codecov Report
@@ Coverage Diff @@
## master #192 +/- ##
==========================================
+ Coverage 98.14% 98.21% +0.06%
==========================================
Files 1 1
Lines 54 56 +2
==========================================
+ Hits 53 55 +2
Misses 1 1
Continue to review full report at Codecov.
|
I'm wondering if there is a more general way of approaching this. Could you call the logger from the fallback element? |
@mbrevda yes, I think I could. Though it still leaves the need of |
Considering SRP, would it seem true that this lib's responsability is simply loading images/fallbacks? In which case, we can use composition to layer additional responsibilities. A yet unreleased prop would act as an image wrapper, allowing post processing scenarios such as logging and animations. To use, create a log element which receivse these props. When it loads, if Would that work for your use case? |
Its responsibility will still be simply loading images/fallbacks. The component itself will not start doing logs/any other unrelated start to it. It will just give a consumer of it an ability to do it. class MyComponent extends React.Component {
render() {
<div>
<Img src={this.props.imageSrc} onLoad={() => this.setState({showAnotherThing: true})} onError={sendErrorLog} />
{this.state.showAnotherThing ? <AnotherThing/> : null}
</div>
}
} vs class MyComponent extends React.Component {
render() {
<div>
<Img src={this.props.imageSrc} fallbackComponent={WrappedFallbackComponent} container={children => children; /* and I need to find a way to setState for showAnotherThing here for example */}>
{this.state.showAnotherThing ? <AnotherThing/> : null}
</div>
}
}
WrappedFallbackComponent = withErrorLogger(FallbackComponent); |
Setup would actually be similar to this: // image wrapper for images that have loaded succesfully
class ImageOkContainer extends Component {
componentDidRender(){
// update logging server that we have show the image
if (this.props.src) console.log('Image loaded successfully!')
}
render() {
return this.props.children
? this.props.children()
: <img {...this.props} />
}
} // unloader, used as a fallback if all images fail to load
class Unloader extends Component {
componentDidRender(){
// log failed to load error
console.error('Image failed to load!')
}
render() {
return <span>Image failed to load!</span>
}
} // demo component
<Img
src={this.props.imageSrc}
loader={<span>Loading...</span>}
unloader={Unloader}
container={ImageContainer}
/> |
@mbrevda this is pretty much what I showed. So first, comparing the two approaches, the one with callbacks is very concise and very react-way and second is verbose and also kind of react way, but in a bit different way and I'd stick with the callbacks. |
To pass the loaded state back to the parent, you could do: // image wrapper for images that have loaded succesfully
class ImageOkContainer extends Component {
componentDidRender(){
// update logging server that we have show the image
if (this.props.src) {
console.log('Image loaded successfully!')
this.props.parentNotifier(true)
}
}
render() {
return this.props.children
? this.props.children()
: <img {...this.props} />
}
} class MyComponenet extends Component {
constructor(){
this.setImageLoadState = this.setImageLoadState.bind(this)
}
setImageLoadState(imageLoaded) {
this.setState({imageLoaded})
}
render() {
<Img
src={this.props.imageSrc}
loader={<span>Loading...</span>}
unloader={Unloader}
container={props => <ImageContainer {...props} parentNotifier={this.setImageLoadState} />}
/>
}
} |
also, I dont understand what I also wonder if what your trying to do can be accomplished today: you can use the |
@mbrevda yes, that's what I meant by "I would need to pass this callback to the container property anyway". So, you see the difference between the example you give me and an example with callbacks?
If I used just |
Perhaps I'm not following, but I'm not convinced that anything needs to be added here. Regardless of the method, you'll need to use callbacks to hoist the state up to the parent. |
I would also like to the |
|
It is now possible to inject a custom image loader with any desired behavior. You can pass it as a prop to the |
1 similar comment
It is now possible to inject a custom image loader with any desired behavior. You can pass it as a prop to the |