admin管理员组文章数量:1405393
Hi I have a scenario where i need to replace setState callback after setting new state in react hooks with React_hooks in a particular scenario.
The current code is::
const ThemeOptions = () => {
const [previewType, setPreviewType] = useState("Desktop");
const [previewUrl, setPreviewUrl] = useState("");
const [layout, setLayout] = useState(null);
const [saving, setSaving] = useState(false);
const handleSave = (newdata) => {
setLayout(newdata);
setSaving(true);
axios
.put(window.urls.save, this.state.layout)
.then(
function(response) { // i want this to change in hooks
this.setState(
{
layout: response.data,
saving: false,
},
function() {
this.refs["preview"].refresh();
}
);
}.bind(this)
)
.catch(
function(error) {
console.log(error);
setSaving(false);
}.bind(this)
);
}
return (
<div>
<Router>
<div className="theme_options">
<div className="row" style={{ height: 100 + "vh" }}>
<Sidebar
layout={layout}
onSave={handleSave}
onReset={this.handleReset}
previewType={previewType}
onChangeScreen={handlePreviewScreenChange}
saving={saving}
/>
<div className="col main">
<span className="d-none d-md-block">
<Preview
ref="preview"
type={this.state.previewType}
url={this.state.previewUrl}
/>
</span>
</div>
</div>
</div>
</Router>
</div>
)
}
I want the success callback function of axios.put requests to be changed in hooks as in the above code there is usage of setState along with callback in it.
The major code to refactor is::
this.setState(
{
layout: response.data,
saving: false,
},
function() {
this.refs["preview"].refresh();
}
);
I was thinking of doing ::
useEffect(()=> {
// i dont know what to put there...
),[]);
I want the callback in setState() to happen in react hooks. Kindly suggest me an ideal way to do this considering the above code.
Hi I have a scenario where i need to replace setState callback after setting new state in react hooks with React_hooks in a particular scenario.
The current code is::
const ThemeOptions = () => {
const [previewType, setPreviewType] = useState("Desktop");
const [previewUrl, setPreviewUrl] = useState("");
const [layout, setLayout] = useState(null);
const [saving, setSaving] = useState(false);
const handleSave = (newdata) => {
setLayout(newdata);
setSaving(true);
axios
.put(window.urls.save, this.state.layout)
.then(
function(response) { // i want this to change in hooks
this.setState(
{
layout: response.data,
saving: false,
},
function() {
this.refs["preview"].refresh();
}
);
}.bind(this)
)
.catch(
function(error) {
console.log(error);
setSaving(false);
}.bind(this)
);
}
return (
<div>
<Router>
<div className="theme_options">
<div className="row" style={{ height: 100 + "vh" }}>
<Sidebar
layout={layout}
onSave={handleSave}
onReset={this.handleReset}
previewType={previewType}
onChangeScreen={handlePreviewScreenChange}
saving={saving}
/>
<div className="col main">
<span className="d-none d-md-block">
<Preview
ref="preview"
type={this.state.previewType}
url={this.state.previewUrl}
/>
</span>
</div>
</div>
</div>
</Router>
</div>
)
}
I want the success callback function of axios.put requests to be changed in hooks as in the above code there is usage of setState along with callback in it.
The major code to refactor is::
this.setState(
{
layout: response.data,
saving: false,
},
function() {
this.refs["preview"].refresh();
}
);
I was thinking of doing ::
useEffect(()=> {
// i dont know what to put there...
),[]);
I want the callback in setState() to happen in react hooks. Kindly suggest me an ideal way to do this considering the above code.
Share Improve this question edited Feb 13, 2020 at 18:02 user12893845 asked Feb 13, 2020 at 17:49 user12893845user12893845 1764 silver badges13 bronze badges 4-
1
Are you sure that you want to replace
setState
byuseEffect
? – Maksym Bezruchko Commented Feb 13, 2020 at 17:56 -
useEffect works similar to ponentDidMount and ponentDidUpdate. So I guess you want to put
function() { this.refs["preview"].refresh(); }
there. See reactjs/docs/hooks-effect.html for reference But setState can't be replaced with useEffect - setState is used before render, and useEffect after. The name useEffect is from triggering side-effect like changing page title. – Zydnar Commented Feb 13, 2020 at 17:56 - I only want the setState callback to happen after state is changed in react hooks. <kindly point me in some direction. – user12893845 Commented Feb 13, 2020 at 18:01
- @Zydnar i am not trying to replace setState with useEffect but i am trying to replicate the callback of setState through useEffect(); – user12893845 Commented Feb 13, 2020 at 18:22
2 Answers
Reset to default 5so this is a very simple yet difficult puzzle which many person find it hard to tackle. Use the below code and it will for sure run and execute its task perfectly:: in the state add one additional flag of 'isError' :
const [layout, setLayout] = useState(null);
const [saving, setSaving] = useState(false);
const [iserror, setIserror] = useState(true);
and use a useEffect like below. The first time useeffect will run but since the condions in useeffect is of specific type it will not run the IF block at all.and IF block will run only on specific conditions mentioned below. But mind it that useEffect will run everytime any of the dependency array elements change but the IF block will not execute at all.
useEffect(()=>{
if(layout && !saving && !iserror){
console.log('specific case render ');
this.refs["preview"].refresh();
}
},[layout,saving,iserror]);
had we put the default conditions of states in IF block then only IF block inside effect would run which is not the case as mentioned above. As we want the setState callback to run only after some specific condition and not always. If we change the above code to something like this then::
//for understanding purpose only default states
layout==null,
saving == false
isError== true
//
useEffect(()=>{
if(layout == null && !saving && iserror){ //observe this default case
console.log('default case render ');
}
},[layout,saving,iserror]);
The handleSave function will do its task with little change::
const handleSave = (newdata) => {
setLayout(newdata); // useEffect run as layout changed but conditions
// not satisfied
setSaving(true); // useEffect will run since saving changed
// not satisfied
axios
.put(window.urls.save, layout)
.then(
function(response) { // only this case forces the code in
// useEffect to run as 3 below cases are
// satisfied
setLayout(response.data);
setSaving(false);
setIserror(false);
}.bind(this)
)
.catch(
function(error) {
console.log(error);
setSaving(false);// only 2 case satisfied i.e layout before
// axios line and saving but not iserror.
setIserror(true);
}.bind(this)
);
}
Hope it helps.
setState is asynchronous. In your case axios executed before setLayout will get updated
const handleSave = (newdata) => {
axios
.put(window.urls.save, this.state.layout)
.then(
function(response) { // i want this to change in hooks
setLayout(response.data);
setSaving(false);
this.refs["preview"].refresh();
}.bind(this)
)
.catch(
function(error) {
console.log(error);
setSaving(false);
}.bind(this)
);
}
useEffect(()=>{
setLayout(newdata);
setSaving(true);
if(newData) handleSave(newData)
},[newData,saving])
and also use setchange while onSave funtion.
<Sidebar
layout={layout}
onSave={(data)=>setLayout(data)}
onReset={this.handleReset}
previewType={previewType}
onChangeScreen={handlePreviewScreenChange}
saving={saving}
/>
本文标签:
版权声明:本文标题:javascript - Replace of setState callback in react hook with useEffect hooks for complicated scenario not working - Stack Overfl 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744293787a2599242.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论