Avoid function to run again and again in ReactJs - reactjs

I created component which take props and this component filter the props but whenever state is changed it re-assign the variable.
Example:
const Foo = (props) => {
const [state, setState] = useState();
const schema = array_filter(props.data, "schema");
// other Code
}
Everytime when state is changed array_filter method is called. array_filter function is custom function which filter the array. I want to avoid extra running of array_filter function. How can I do that can you please let me know.
I try useRef but not working.

Just cache your result and it only re-calculates as your input is changed which is best in your case:
const schema = React.useMemo(() => array_filter(props.data, "schema"), [props.data]);

Related

Why is there a function call in a useState() hook in React sometimes? And what does it mean? [duplicate]

I am new to react Hooks. Am trying to make use of useState in my code. While I was using it I found a term "Lazy initial state"
https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [state, setState] = useState(() => {
const initialState = someExpensiveComputation(props);
return initialState;
});
But I am not able to think of any use case where this lazy initialising of state will be useful.
Like say my DOM is rendering and it needs the state value, but my useState has not initialised it yet! And say if you have rendered the DOM and the someExpensiveComputation has finished, the DOM will re-render!
The value passed to the useState hook in the initial render is the initial state value, and gets disregarded in subsequent renders. This initial value can be the result of calling a function as in the following situation:
const Component = () => {
const [state, setState] = useState(getInitialHundredItems())
}
But note that getInitialHundredItems is unconditionally and needlessly called on each render cycle.
For use cases like this instead of just calling a function that returns a value you can pass a function which returns the initial state. This function will only be executed once (initial render) and not on each render like the above code will. See Lazy Initial State for details.
const Component = () =>{
const [state, setState] = useState(getInitialHundredItems)
}

React useState(0) vs useState( () => 0 )

I saw React codes generally use arrow function for setState(). However, for useState(), I see that they just put a number, eg useState(0) instead of arrow function, ie useState( () => 0 )
Are there any reasons why I would want to use an arrow function in useState ? Is it alright to use only arrow functions for ALL React hook regardless, including initialising the hook. Any gotcha ? Thanks very much.
For your simple case it does not matter. You are just making an extra function call which returns a value without any computation.
But in case your initial state is a result of an expensive computation you can use a function.
Using the below
const [state, setState] = useState(() => {
const initialState = someExpensiveComputation(props);
return initialState;
});
instead of
const [state, setState] = useState(someExpensiveComputation(props));
matters greatly.
The initialState argument is the state used during the initial render. In subsequent renders, it is disregarded.
So even when your value is disregarded you would be making that expensive computation. You can provide a function in your useState which will only run on the very first render, like in the second case above. [Link](The initialState argument is the state used during the initial render. In subsequent renders, it is disregarded.)
As far as I know, the arrow functions in state setter permit use the previous state.
For example:
const [message, setMessage] = useState('hello ')
... # Receive data from a form or API, etc.
let name = 'Richard'
setMessage(old_state => old_state + name) # 'hello Richard'
This way, you can create counter or reuse some data of the previous state.
Use setState(new_vale) is totally correct for reset the value.

Combining useState and useRef in ReactJS

I have some variables of which I need the reference as well as the state. I found something here, that helped me: https://stackoverflow.com/a/58349377/7977410
Pretty much it just kept two variables synchronized (in pseudo code):
const [track, setTrack] = useState('INIT');
const trackRef = useRef('INIT');
// Whenever changing, just both are updated
setTrack('newValue');
trackRef.current = 'newValue';
I was wondering if it was beneficial to combine those two into a new hook. Something like this:
const useStateRef(initialState: any) {
const [state, setState] = useState<typeof initialState>(initialState);
const ref = useRef<typeof initialState>(initialState);
useEffect(() => {
setState(ref);
}, [ref]);
return [state, ref];
}
What would be the best way to do this? Is it even critical to do something like this?
(The background is, I have some self-repeating functions, that need the reference to change what they are doing. But I also need the state variable to rerender visible changes when the same variables are changing... Maybe there is a completely different way to do this, but I am still curious about this approach.)
It's possible, but to make the typings proper, you should use generics instead of any, and the effect hook needs to be reversed - change the ref.current when the state changes. You'll also want to return the state setter in order to change the value in the consumer of useStateRef.
const useStateRef = <T extends unknown>(initialState: T) => {
const [state, setState] = useState(initialState);
const ref = useRef(initialState);
useEffect(() => {
ref.current = state;
}, [state]);
// Use "as const" below so the returned array is a proper tuple
return [state, setState, ref] as const;
};
Or, to update synchronously, remove the effect hook:
if (ref.current !== state) ref.current = state;
Also note that there should never be any need to have a ref that only ever contains a primitive. const trackRef = useRef('INIT'); can be refactored away entirely and replaced with track. Refs are generally useful when dealing with objects, like HTMLElements.

confused about Lazy Initialization of React useState [duplicate]

I am new to react Hooks. Am trying to make use of useState in my code. While I was using it I found a term "Lazy initial state"
https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [state, setState] = useState(() => {
const initialState = someExpensiveComputation(props);
return initialState;
});
But I am not able to think of any use case where this lazy initialising of state will be useful.
Like say my DOM is rendering and it needs the state value, but my useState has not initialised it yet! And say if you have rendered the DOM and the someExpensiveComputation has finished, the DOM will re-render!
The value passed to the useState hook in the initial render is the initial state value, and gets disregarded in subsequent renders. This initial value can be the result of calling a function as in the following situation:
const Component = () => {
const [state, setState] = useState(getInitialHundredItems())
}
But note that getInitialHundredItems is unconditionally and needlessly called on each render cycle.
For use cases like this instead of just calling a function that returns a value you can pass a function which returns the initial state. This function will only be executed once (initial render) and not on each render like the above code will. See Lazy Initial State for details.
const Component = () =>{
const [state, setState] = useState(getInitialHundredItems)
}

What am I doing wrong Hooks Related

I am new to hooks so I will ask this question:
How can I legally use setState inside a onChange function ??
{
const state = useState([{date: date}]);
};
This throws an error :(
Expected: update the state
And result error message: Hooks can only be called inside the body of a function component.
I did find some answers on the web about multiple React version installed but this is not the case here :)
You need to declare your hook in the body of your main component function:
const MyComponent = () => {
// declaring your useState Hook - it returns a getter and setter
const [date, setDate] = useState(null)
const myCallback = (newDate)=>{
// you can read the state
const state = date;
// or, you can do the equivalent of setState
setDate(newDate)
}
return // return your .jsx
}
The things to note are that you declare your hook once, and that it returns two parameters, a getter and a setter. From then on, you interact with that original Hook using the getter and setter only.
For your pastebin code:
const [myState,setMyState] = useState(
{
name: "",
type: props.navigation.getParam("serviceName"),
date: "15-05-2018",
imageURI: props.navigation.getParam("imageURI")
});
const handleChange = e => {
setMyState(prevState=> {...prevState, name: e.nativeEvent.text})
};
(I've used myState and setMyState but they can be whatever you like)
Hmm it seems you've got it wrong...
There's no single state when we use hooks like in the case of a class,
const [item, setValue] = useState(null)
this sets the state variable "item" with initial value of null. Now we can use the "setValue" to change the value of "item" to what we want like this
setValue(5).There is no setState as in the case of a class component. Since the value of a state variable has been changed the component rerenders. We can declare multiple state-variables like
const [newitem, setnewItemValue] = useState(null) and whenever a state-variable changes the component will rerender

Resources