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
- Label list is not showing in recharts?
- What is necessary to fire Tracker's autorun function?
- Clarifai - FACE DETECT - Model does not exist
- Styled components nested rules don't work
- ReactJS - create a separate file for functions that dispatch actions
- Infer generic type between 2 props in React TypeScript
- How to show <Skeleton.Image /> only in loading component (Ant Design)
- React-hot-loader: react-🔥-dom patch is not detected
- how to make a custom and reusable table component in typescript react?
- How to increase material-ui icons?
- reactjs - can not read property push of undefined
- How to structure a React app to pass values returned from a child's function
- Lazy loading reactJS app with laravel backend
- multer: can do [req.file.filename] but need [req.files[0].filename] or [req.files.find({fieldname:"samplefield"})]
- React & Reselect selector claims state is the same after update
- Redux vs custom hook
- Save state after refresh
- Context API loses data on switching router links
- React Router Route Params in Redux
- OnClick Event binding in React.js while code is in variable
- Styled-component, using theme variables in Render
- Is it possible to randomly hash classes with build process?
- How can i dispatch something with react+redux+router from nav item without render anything?
- Form Validation in material UI React - how to implement form validation for dropdown list
- Lifting state from child component to parent
- Get state value without using useSelector
- Deploy React Starter Kit (by Kriasoft) to Heroku
- How to set cookie from flask to reactjs
- How to change only the current (this) element inside a loop with useState in React?
- Selenium (Python) + React