score:135
you can use useeffect/uselayouteffect to achieve this:
const somecomponent = () => {
const [count, setcount] = react.usestate(0)
react.useeffect(() => {
if (count > 1) {
document.title = 'threshold of over 1 reached.';
} else {
document.title = 'no threshold reached.';
}
}, [count]);
return (
<div>
<p>{count}</p>
<button type="button" onclick={() => setcount(count + 1)}>
increase
</button>
</div>
);
};
if you want to prevent the callback from running on first render, adjust the previous version:
const somecomponent = () => {
const [count, setcount] = react.usestate(0)
const didmount = react.useref(false);
react.useeffect(() => {
if (!didmount.current) {
didmount.current = true;
return;
}
if (count > 1) {
document.title = 'threshold of over 1 reached.';
} else {
document.title = 'no threshold reached.';
}
}, [count]);
return (
<div>
<p>{count}</p>
<button type="button" onclick={() => setcount(count + 1)}>
increase
</button>
</div>
);
};
more about it over here.
score:3
function parent() {
const [name, setname] = usestate("");
getchildchange = getchildchange.bind(this);
function getchildchange(value) {
setname(value);
}
return <div> {name} :
<child getchildchange={getchildchange} ></child>
</div>
}
function child(props) {
const [name, setname] = usestate("");
handlechange = handlechange.bind(this);
collectstate = collectstate.bind(this);
function handlechange(ele) {
setname(ele.target.value);
}
function collectstate() {
return name;
}
useeffect(() => {
props.getchildchange(collectstate());
});
return (<div>
<input onchange={handlechange} value={name}></input>
</div>);
}
useeffect
act as componentdidmount, componentdidupdate, so after updating state it will work
score:3
you can utilize usecallback hook to do this.
function parent() {
const [name, setname] = usestate("");
const getchildchange = usecallback( (updatedname) => {
setname(updatedname);
}, []);
return <div> {name} :
<child getchildchange={getchildchange} ></child>
</div>
}
function child(props) {
const [name, setname] = usestate("");
function handlechange(ele) {
setname(ele.target.value);
props.getchildchange(ele.target.value);
}
function collectstate() {
return name;
}
return (<div>
<input onchange={handlechange} value={name}></input>
</div>);
}
score:5
another way to achieve this:
const [name, setname] = usestate({val:"", callback: null});
react.useeffect(()=>{
console.log(name)
const {callback} = name;
callback && callback();
}, [name]);
setname({val:'foo', callback: ()=>setname({val: 'then bar'})})
score:7
we can write customise function which will call the callback function if any changes in the state
import react, { usestate, useeffect } from "react";
import reactdom from "react-dom";
import "./styles.css";
const usestatecallbackwrapper = (initilvalue, callback) => {
const [state, setstate] = usestate(initilvalue);
useeffect(() => callback(state), [state]);
return [state, setstate];
};
const callback = state => {
console.log("---------------", state);
};
function app() {
const [count, setcount] = usestatecallbackwrapper(0, callback);
return (
<div classname="app">
<h1>{count}</h1>
<button onclick={() => setcount(count + 1)}>+</button>
<h2>start editing to see some magic happen!</h2>
</div>
);
}
const rootelement = document.getelementbyid("root");
reactdom.render(<app />, rootelement);
`
score:11
actually, you should avoid using this
when using react hooks. it causes side effects. that's why react team create react hooks
.
if you remove codes that tries to bind this
, you can just simply pass setname
of parent
to child
and call it in handlechange
. cleaner code!
function parent() {
const [name, setname] = usestate("");
return <div> {name} :
<child setname={setname} ></child>
</div>
}
function child(props) {
const [name, setname] = usestate("");
function handlechange(ele) {
setname(ele.target.value);
props.setname(ele.target.value);
}
return (<div>
<input onchange={handlechange} value={name}></input>
</div>);
}
moreover, you don't have to create two copies of name
(one in parent
and the other one in child
). stick to "single source of truth" principle, child
doesn't have to own the state name
but receive it from parent
. cleanerer node!
function parent() {
const [name, setname] = usestate("");
return <div> {name} :
<child setname={setname} name={name}></child>
</div>
}
function child(props) {
function handlechange(ele) {
props.setname(ele.target.value);
}
return (<div>
<input onchange={handlechange} value={props.name}></input>
</div>);
}
score:35
with react16.x and up, if you want to invoke a callback function on state change using usestate
hook, you can use the useeffect
hook attached to the state change.
import react, { useeffect } from "react";
useeffect(() => {
props.getchildchange(name); // using camelcase for variable name is recommended.
}, [name]); // this will call getchildchange when ever name changes.
score:105
setstate(updater, callback)
for usestate
following implementation comes really close to the original setstate
callback of classes.
improvements made to accepted answer:
- callback execution is omitted on initial render - we only want to call it on state updates
- callback can be dynamic for each
setstate
invocation, like with classes
usage
const app = () => {
const [state, setstate] = usestatecallback(0); // same api as usestate
const handleclick = () => {
setstate(
prev => prev + 1,
// second argument is callback, `s` being the *updated* state
s => console.log("i am called after setstate, state:", s)
);
};
return <button onclick={handleclick}>increment</button>;
}
usestatecallback
function usestatecallback(initialstate) {
const [state, setstate] = usestate(initialstate);
const cbref = useref(null); // init mutable ref container for callbacks
const setstatecallback = usecallback((state, cb) => {
cbref.current = cb; // store current, passed callback in ref
setstate(state);
}, []); // keep object reference stable, exactly like `usestate`
useeffect(() => {
// cb.current is `null` on initial render,
// so we only invoke callback on state *updates*
if (cbref.current) {
cbref.current(state);
cbref.current = null; // reset callback after execution
}
}, [state]);
return [state, setstatecallback];
}
further info: react hooks faq: is there something like instance variables?
working example
const app = () => {
const [state, setstate] = usestatecallback(0);
const handleclick = () =>
setstate(
prev => prev + 1,
// important: use `s`, not the stale/old closure value `state`
s => console.log("i am called after setstate, state:", s)
);
return (
<div>
<p>hello comp. state: {state} </p>
<button onclick={handleclick}>click me</button>
</div>
);
}
function usestatecallback(initialstate) {
const [state, setstate] = usestate(initialstate);
const cbref = useref(null);
const setstatecallback = usecallback((state, cb) => {
cbref.current = cb;
setstate(state);
}, []);
useeffect(() => {
if (cbref.current) {
cbref.current(state);
cbref.current = null;
}
}, [state]);
return [state, setstatecallback];
}
reactdom.render(<app />, document.getelementbyid("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32gmw5rbdxymjg/73fgpukotzdmrxuyw7tj8adbn8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjq42ac3en0gqk40pc9ggi/yixvkyz24qmp/9higw7w=" crossorigin="anonymous"></script>
<script>var { usereducer, useeffect, usestate, useref, usecallback } = react</script>
<div id="root"></div>
Source: stackoverflow.com
Related Query
- How to use callback with useState hook in react
- How to use React Context with useState hook to share state from different components?
- How to use useState hook in React with typescript correctly?
- How to use React useRef hook with typescript?
- How to prevent race conditions with react useState hook
- how can I test if useState hook has been called with jest and react testing library?
- How to use the useState hook with asynchronous calls to change an array?
- How does React useState hook work with mutable objects
- How to use React Hook Form with Typescript (Input Component)
- How to use useCallback hook with onChange function REACT
- How to use onChange with react hook on react select to change data base on user select
- Typescript error when use react useState hook with generics
- React updating a setState with a callback to a useState hook
- How to use a custom React hook to make a POST or DELETE request with Axios
- React useState hook with callback
- How do I update 2 objects with React Hook useState
- How do I use the useState hook to change the color of my react icons to blue?
- How to use the react spring hook with react. Basic code not working
- How to use callback with useState like setState in class components?
- How to use react Hook state variables without a callback function?
- How to use useState hook with formik
- React - using a callback function with useState Hook
- How to use useState in React 15 with react-bootstrap
- how can i pass a useState hook defined with typescript down to another react component?
- React with TypeScript: how to type useState hook with previous state
- how to use react fetch() with useEffect hook and map the fetched data
- How to use array.reduce() with react hook useState, useEffect?
- How can I use reactjs useState hook without broke my react app?
- React - How to use hook useState props to create a map function
- how to use usestate with node.js backend and react frontend
More Query from same tag
- Raycaster display a Render
- React - unique key in object gets overwritten when updating state array
- Getting numerical elements from Odometer syntax in Cypress
- React Router Navbar background change only works in pages folder, but not on App.js?
- Can't export action creator to component mapDispatchToProps method
- what is the use of 'jsx' property in tsconfig.json
- Welcome page/ first launch page using react/next.js
- Can't seem to use Aliases for importing in Webpack 5
- Unable to stop the propogation of events in reactJs
- How to load external svg file in `SvgIcon` in material-ui?
- React Router | Component not getting rendered
- react-hook-form: using readyOnly in a select element
- React update checkbox from object value
- Webpack 4 and react loadable does not seems to create correct chunk for server side rendering
- How to prevent set state before useEffect?
- valid prop not works in the styled-component. It gives a warning
- mobx: array.map() is not a function
- destructing nested object in react prop got error
- Save React-Bootstrap xs,sm,md,lg,xl spans/offsets into css class
- passport.changePassword is not a function - passort-local-mongoose
- D3 draw circles around arc
- Why does axios post method stop working after 6 consecutive post calls?
- rc calendar when I select the date in the calendar its not changing in the textbox
- React timer component percentage
- Does material-ui useStyles really requires the entire props object?
- React Router with Loadable Components error
- Pass props from parent to child component that uses hooks?
- Update nested array ES6, JavaScript
- How to read a .tif file using React.js or other Javascsript libraries?
- onBlur for div element in React