My question is this. I have two components. First component is an image cropper. Second component is the one that i should display the cropped image.
The problem i'm facing is i can pass the cropped image to my second component but i have to press the button that crops the image and pass to the second component, twice. On the second click only my image is passing to the second component. But i can display the cropped image in the first component only by one click. I think it is happening because in reactjs state changes are not occurring immediately. So how can i fix this.
My approach was to create a prop
function in the 1st component as this.props.croppedImage(this.state.preview.img);
here this.state.preview.img
is the cropped image. And in the 2nd component i'm getting the cropped image by calling the prop function.
My code
1st component (cropper)
class CropperTest extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "beautiful",
scale: 1,
preview: null,
}
this.handleSave = this.handleSave.bind(this);
}
handleSave = () => {
const img = this.editor.getImageScaledToCanvas().toDataURL();
this.setState({
preview: {
img,
scale: this.state.scale,
}
})
this.props.croppedImage(this.state.preview.img);
}
setEditorRef = (editor) => {
this.editor = editor
}
render() {
return (
<div>
<div className="overlay"></div>
<div className="crop_div">
<AvatarEditor
image={this.props.cropImage}
ref={this.setEditorRef}
width={450}
height={450}
border={50}
color={[255, 255, 255, 0.6]} // RGBA
scale={this.state.scale}
rotate={0}
/>
</div>
<div className="zoom_slider text_align_center">
<input className="crop_btn" type='button' onClick={this.handleSave} value='Save'/>
</div>
</div>
)
}
}
export default CropperTest;
2nd component
Here i'm basically doing the following.
<CropperTest croppedImage = {this.getCroppedImg}/>
getCroppedImg(img){
alert("Perfect Storm");
this.setState({
previewImg:img
})
}
So if you want to perform an action immediately after setting state on a state variable, we need to pass a callback function to the setState function. But in a functional component no such callback is allowed with useState hook. In that case we can use the useEffect hook to achieve it.
The first and most commonly used method to run a function after updating state is the useEffect hook. useEffect runs its function only when the items in the dependency array change.
When a value in the state object changes, the component will re-render, meaning that the output will change according to the new value(s).
Show activity on this post. Yes you can.
I think it is happening because in reactjs state changes are not occurring immediately. So how can i fix this?
From the React#setState
,
setState(updater, [callback])
setState()
enqueues changes to the component state. ThesetState
doesn't immediately update the state.setState()
does not always immediately update the component. It may batch or defer the update until later. This makes readingthis.state
right after callingsetState()
a potential pitfall.Instead, usecomponentDidUpdate
or asetState
callback(setState(updater, callback))
Call the this.props.croppedImage
in the setState
callback.You will get updated values of component state. In your case its this.state.preview
this.setState({
preview: {
img,
scale: this.state.scale,
}
}, () => {
this.props.croppedImage(this.state.preview.img);
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With