Skip to content

Commit de1a6a1

Browse files
committed
useState return values
1 parent 521d2b5 commit de1a6a1

5 files changed

+171
-59
lines changed

React/hooks-useEffect.md

+34-36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.
44

5+
Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React’s render phase). Doing so will lead to confusing bugs and inconsistencies in the UI. **According to doc function passed to useEffect fires after layout and paint.**
6+
57
[https://reactjs.org/docs/hooks-effect.html](https://reactjs.org/docs/hooks-effect.html) - The Effect Hook lets you perform side effects in function components. Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects.
68

79
In React class components, the render method itself shouldn’t cause side effects. It would be too early — we typically want to perform our effects after React has updated the DOM.
@@ -19,32 +21,28 @@ This is why in React classes, we put side effects into `componentDidMount` and `
1921

2022
```js{9-15}
2123
class Example extends React.Component {
22-
constructor(props) {
23-
super(props);
24-
this.state = {
25-
count: 0
26-
};
27-
}
28-
componentDidMount() {
29-
document.title = `You clicked ${this.state.count} times`;
30-
}
31-
componentDidUpdate() {
32-
document.title = `You clicked ${this.state.count} times`;
33-
}
34-
render() {
35-
return (
36-
<div>
37-
<p>You clicked {this.state.count} times</p>
38-
<button
39-
onClick={() =>
40-
this.setState({ count: this.state.count + 1 })
41-
}
42-
>
43-
Click me
44-
</button>
45-
</div>
46-
);
47-
}
24+
constructor(props) {
25+
super(props);
26+
this.state = {
27+
count: 0
28+
};
29+
}
30+
componentDidMount() {
31+
document.title = `You clicked ${this.state.count} times`;
32+
}
33+
componentDidUpdate() {
34+
document.title = `You clicked ${this.state.count} times`;
35+
}
36+
render() {
37+
return (
38+
<div>
39+
<p>You clicked {this.state.count} times</p>
40+
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
41+
Click me
42+
</button>
43+
</div>
44+
);
45+
}
4846
}
4947
```
5048

@@ -59,16 +57,16 @@ We've already seen this example at the top of this page, but let's take a closer
5957
```js{1,6-8}
6058
import React, { useState, useEffect } from "react";
6159
function Example() {
62-
const [count, setCount] = useState(0);
63-
useEffect(() => {
64-
document.title = `You clicked ${count} times`;
65-
});
66-
return (
67-
<div>
68-
<p>You clicked {count} times</p>
69-
<button onClick={() => setCount(count + 1)}>Click me</button>
70-
</div>
71-
);
60+
const [count, setCount] = useState(0);
61+
useEffect(() => {
62+
document.title = `You clicked ${count} times`;
63+
});
64+
return (
65+
<div>
66+
<p>You clicked {count} times</p>
67+
<button onClick={() => setCount(count + 1)}>Click me</button>
68+
</div>
69+
);
7270
}
7371
```
7472

React/hooks-useReducers.md

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
**useReducer hook accepts two arguments first argument is reducer function and second argument is initial app state then it return array with two elements - state and a dispatch function.**
2+
3+
A Reducer Hook returns us a state object and a function to alter the state object. The function – called dispatch function – takes an action which has a type and an optional payload. All this information is used in the actual reducer function to distill a new state from the previous state, the action’s optional payload and type.
4+
5+
Given the return value from **useReducer** is in the form object, I can do de-structuring to get the named-properties from that object by doing this.
6+
7+
`const [state, dispatch] = useReducer(reducer, initialState)`
8+
9+
By the [Official doc on the above array-destructuring synatax](https://reactjs.org/docs/hooks-state.html#tip-what-do-square-brackets-mean)
10+
11+
It means that we’re making two new variables **state** and **dispatch**, where **state** is set to the first value returned by **useReducer**, and **dispatch** is the second. It is equivalent to this code:
12+
13+
Every useReducer comes with its own dispatch function.
14+
15+
The **useReducer** function is tightly coupled to its reducer and its dispatch function. We dispatch action objects to that reducer only.
16+
17+
#### Now an example to convert a useState() to a useReducer()
18+
19+
[https://reactjs.org/docs/hooks-reference.html#usestate](https://reactjs.org/docs/hooks-reference.html#usestate)
20+
21+
**First useState implementation of a typical counter button**
22+
23+
```js
24+
function Counter({ initialCount }) {
25+
const [count, setCount] = useState(initialCount);
26+
return (
27+
<>
28+
Count: {count}
29+
<button onClick={() => setCount(initialCount)}>Reset</button>
30+
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
31+
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
32+
</>
33+
);
34+
}
35+
```
36+
37+
Syntax
38+
39+
`const [state, dispatch] = useReducer(reducer, initialArg, init)`
40+
41+
An alternative to useState. Accepts a reducer of type (state, action) => newState, and returns the current state paired with a dispatch method.
42+
43+
Here’s the counter example from the useState section, rewritten to use a reducer:
44+
45+
```js
46+
const initialState = { count: 0 };
47+
48+
function reducer(state, action) {
49+
switch (action.type) {
50+
case "increment":
51+
return { count: state.count + 1 };
52+
case "decrement":
53+
return { count: state.count - 1 };
54+
default:
55+
throw new Error();
56+
}
57+
}
58+
59+
function Counter() {
60+
const [state, dispatch] = useReducer(reducer, initialState);
61+
return (
62+
<>
63+
Count: {state.count}
64+
{/* dispatching the type of action*/}
65+
<button onClick={() => dispatch({ type: "increment" })}>+</button>
66+
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
67+
</>
68+
);
69+
}
70+
```
71+
72+
**A GENERAL EXAMPLE**
73+
74+
**The dispatch function can be used to send an action to the reducer which would implicitly change the current state:**
75+
76+
```JS
77+
const [todos, dispatch] = React.useReducer(todoReducer, initialTodos);
78+
79+
dispatch({ type: 'DO_TODO', id: 'a' });
80+
```
81+
82+
#### Compare it with how Redux dispatch() works
83+
84+
Dispatches an action. This is the only way to trigger a state change. dispatch() is one of the 4 methods of redux-store. dispatch() is the method used to dispatch actions and trigger state changes to the store. So the way we take `actions` to the `store` is `dispatch`
85+
86+
The store's reducing function will be called with the current getState() result and the given action synchronously. Its return value will be considered the next state. It will be returned from getState() from now on, and the change listeners will immediately be notified.
87+
88+
There are a few rules of thumb to follow: If you state management doesn’t need all the Redux features, use useState, useReducer and useContext. If your state management needs Redux as one global state container with middleware, introduce Redux to your application to handle state logic in complex and large applications.
89+
90+
- Use useState for basic and simple/small size applications.
91+
- Use useState + useReducer + useContext for advanced/medium size applications.
92+
- Use useState/useReducer + Redux for complex/large size applications.
93+
94+
#### Further Reading
95+
96+
- 1. [https://www.robinwieruch.de/redux-vs-usereducer/](https://www.robinwieruch.de/redux-vs-usereducer/)
97+
- 2.

React/hooks-useState.md

+17-5
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,26 @@
44
import React, { useState } from "react";
55

66
const Message = () => {
7-
const messageState = useState("");
8-
const listState = useState([]);
7+
const [messageState, setMessageState] = useState("");
8+
const [listState, setListState] = useState([]);
99
};
1010
```
1111

12-
**useState** takes an initial state as an argument, and returns the current state and an updater function.
12+
**useState** takes an initial state as an argument, and returns a pair (the current state and an updater function) as an array with two items. The first item is the current value, and the second is a function that lets us update it.
13+
14+
In the above case the current state is 'messageState' and the updater function is 'setMessageState'. This is similar to this.state.messageState and this.setState in a class component. The **array destructuring** syntax lets us give different names to the state variables we declared by calling useState. These names aren’t a part of the useState API.
15+
16+
By the [Official doc on the above array-destructuring syntax](https://reactjs.org/docs/hooks-state.html#tip-what-do-square-brackets-mean)
17+
18+
It means that we’re making two new variables **messageState** and **setMessateState**, where **messageState** is set to the first value returned by **useState**, and **setMessageState** is the second. It is equivalent to this code:
19+
20+
```js
21+
var messageStateVariable = useState("some message"); // Returns a pair
22+
var messageState = messageStateVariable[0]; // First item in a pair
23+
var setMessageState = messageStateVariable[1]; // Second item in a pair
24+
```
1325

14-
You can pass the initial value of the state variable as an argument directly, as shown in the previous example, or use a function to lazily initialize the variable (useful when the initial state is the result of an expensive computation):
26+
**You can pass the initial value of the state variable as an argument directly, as shown in the previous example, or use a function to lazily initialize the variable (useful when the initial state is the result of an expensive computation):**
1527

1628
```js
1729
const Message = () => {
@@ -56,7 +68,7 @@ const Persons = props => {
5668
};
5769
```
5870

59-
The **setNameState** function is used to update the state. It accepts a new state value and enqueues a re-render of the component. Remember unlike the class-based component's `setState()` method, there is NO `setState()` in react-hooks. So whatever the name of the state is (in this case 'nameState') just add the keyword **set** to that with a proper camel-casing. So here that becomes **setNameState** but this **setNameState** can theoratically become anything.
71+
The **setNameState** function is used to update the state. It accepts a new state value, as its argument and enqueues a re-render of the component. Remember unlike the class-based component's `setState()` method, there is NO `setState()` in react-hooks. So whatever the name of the state is (in this case 'nameState') just add the keyword **set** to that with a proper camel-casing. So here that becomes **setNameState** but this **setNameState** can theoretically be any word.
6072

6173
[https://stackoverflow.com/questions/54625831/how-to-sync-props-to-state-using-react-hook-setstate](https://stackoverflow.com/questions/54625831/how-to-sync-props-to-state-using-react-hook-setstate)
6274

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
While useReducer with its reducer is a part of how Redux works, it isn’t Redux. The useReducer function is tightly coupled to its reducer which holds also true for its dispatch function. We dispatch action objects to that reducer only. Whereas in Redux, the dispatch function sends the action object to the store which distributes it to all its combined reducer functions. You can think of Redux as one global event bus which takes any events (actions) and processes them into a new state based on the action’s payload and the previous state.

React/hooks-Redux-actions-with-useEffect.md renamed to React/hooks-with-Redux-actions-inside-useEffect.md

+22-18
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,6 @@ ReactDOM.render(
1818
**Rubrics.tsx- The main component to render**
1919

2020
```js
21-
const mapStateToProps = state => ({
22-
rubrics: state.rubrics.items,
23-
loading: state.rubrics.loading,
24-
error: state.rubrics.error
25-
});
26-
27-
// THIS IS INCORRECT WAY
28-
// const mapDispatchToProps = dispatch => {
29-
// return {
30-
// getRubrics: () => dispatch(fetchRubrics())
31-
// };
32-
// };
33-
34-
// THIS IS CORRECT WAY - Now you won't be creating a new object every time your component re-renders
35-
const mapDispatchToProps = {
36-
getRubrics: fetchRubrics
37-
};
38-
3921
const Rubrics = props => {
4022
const { getRubrics, loading, error } = props;
4123

@@ -63,6 +45,24 @@ const Rubrics = props => {
6345
);
6446
};
6547

48+
const mapStateToProps = state => ({
49+
rubrics: state.rubrics.items,
50+
loading: state.rubrics.loading,
51+
error: state.rubrics.error
52+
});
53+
54+
// THIS IS INCORRECT WAY
55+
// const mapDispatchToProps = dispatch => {
56+
// return {
57+
// getRubrics: () => dispatch(fetchRubrics())
58+
// };
59+
// };
60+
61+
// THIS IS CORRECT WAY - Now you won't be creating a new object every time your component re-renders
62+
const mapDispatchToProps = {
63+
getRubrics: fetchRubrics
64+
};
65+
6666
export default connect(
6767
mapStateToProps,
6868
mapDispatchToProps
@@ -152,3 +152,7 @@ const rubricReducer = (state = initialState, action) => {
152152
};
153153
export default rubricReducer;
154154
```
155+
156+
#### Further Reading
157+
158+
https://stackoverflow.com/questions/55633900/how-to-dispatch-an-redux-action-to-load-data-inside-useeffect-on-page-load

0 commit comments

Comments
 (0)