forked from reactplay/react-play
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Committing the play for React Transition (reactplay#1206)
* Committing the play for React Transition * Added radio button switch and cover image * More styling changes * fixed lint errors * More linting fixes * Updated Readme * Taken care of review comments
- Loading branch information
Showing
11 changed files
with
267 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,3 @@ | |
grid-gap: 0.3rem; | ||
margin-left: 0.4rem; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { faker } from '@faker-js/faker'; | ||
|
||
const THRESHOLD = 10000; | ||
|
||
export const users = Array.from(Array(THRESHOLD), () => { | ||
return { | ||
name: faker.name.fullName(), | ||
avatar: faker.image.avatar(), | ||
background: faker.image.nature() | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import React, { useState } from 'react'; | ||
|
||
export default function PrioritySearch({ users }) { | ||
const [searchTerm, setSearchTerm] = useState(''); | ||
const [filtered, setFiltered] = useState(users); | ||
|
||
const handleChange = ({ target: { value } }) => { | ||
// Set the search term on the textbox | ||
setSearchTerm(value); | ||
|
||
// Filter the user list based on the search term | ||
setFiltered(users.filter((item) => item?.name.includes(value))); | ||
}; | ||
|
||
return ( | ||
<div className="user-container"> | ||
<h1>User Finder - Priority</h1> | ||
<div>{users.length !== filtered.length ? `${filtered.length} matches` : null}</div> | ||
<input placeholder="Type a name" type="text" value={searchTerm} onChange={handleChange} /> | ||
<div className="user-cards"> | ||
{filtered.length > 0 ? ( | ||
filtered.map((user) => ( | ||
<div class="card"> | ||
<div> | ||
<img alt={`Avatar image of ${user?.name}`} src={user?.avatar} /> | ||
</div> | ||
<div> | ||
<strong>{user?.name}</strong> | ||
</div> | ||
</div> | ||
)) | ||
) : ( | ||
<h4 className="nomatch">No Match Found...</h4> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { useState } from 'react'; | ||
import PlayHeader from 'common/playlists/PlayHeader'; | ||
import './styles.css'; | ||
|
||
import PrioritySearch from './PrioitySearch'; | ||
import TrainsitionSearch from './TransitionSearch'; | ||
|
||
import { users } from 'common/utils/fakeUser'; | ||
|
||
function ReactTransitions(props) { | ||
const [transitionOn, setTransitionOn] = useState(false); | ||
const onValueChange = (event) => { | ||
const val = event.target.value; | ||
if (val === 'transition') { | ||
setTransitionOn(true); | ||
} else { | ||
setTransitionOn(false); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
<div className="play-details"> | ||
<PlayHeader play={props} /> | ||
<div className="react-transition play-details-body"> | ||
<div className="modes"> | ||
<input | ||
checked={transitionOn === false} | ||
id="priority-id" | ||
name="type" | ||
type="radio" | ||
value="priority" | ||
onChange={onValueChange} | ||
/> | ||
<label htmlFor="priority-id">Priority</label> | ||
<input | ||
checked={transitionOn === true} | ||
id="transition-id" | ||
name="type" | ||
type="radio" | ||
value="transition" | ||
onChange={onValueChange} | ||
/> | ||
<label htmlFor="priority-id">Transition</label> | ||
</div> | ||
{transitionOn ? <TrainsitionSearch users={users} /> : <PrioritySearch users={users} />} | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
export default ReactTransitions; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# React Transitions | ||
|
||
A Play to explain the Transitions in React using the useTransition Hook in React 18. | ||
|
||
By default, all the sttate updates are Urgent and High-Priority in React. This | ||
may cause issues when your application state is dealing with a huge list of | ||
data. Some state updates can be marked as non-urgent and that's where the Transition comes in. | ||
|
||
## Play Demographic | ||
|
||
- Language: js | ||
- Level: Intermediate | ||
|
||
## Creator Information | ||
|
||
- User: atapas | ||
- Gihub Link: https://github.com/atapas | ||
- Video: https://www.youtube.com/watch?v=UspVJPxYnQM | ||
|
||
## Implementation Details | ||
In this play, I've shown two modes of the same application. | ||
|
||
The first mode is the regular one without any transition and the second mode | ||
uses the `useTransition` and `setTransition`. | ||
|
||
In the first mode, when you type down the text in the textfield to search down users, | ||
and then try removing the texts fast in the textbox, you will observe a lag. You need | ||
to press the backspace key multiple times to clear of the texts in the textbox. This is an unacceptable behaviour as it is going to make the end users frustrated. | ||
|
||
In the second mode, with the `useTransition` hook, now we can improve this behaviour a lot. The state update with a long list of items been taken care by the `setTransition` as a non-urgent update. | ||
|
||
```js | ||
// Execute Non-Urgent Code | ||
startTransition(() => { | ||
// Filter the user list based on the search term | ||
setFiltered(users.filter((item) => item.name.includes(value))); | ||
}); | ||
``` | ||
|
||
## Consideration | ||
|
||
None | ||
|
||
## Resources | ||
|
||
- [https://www.youtube.com/watch?v=UspVJPxYnQM](https://www.youtube.com/watch?v=UspVJPxYnQM) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import React, { useState, useTransition } from 'react'; | ||
|
||
export default function TrainsitionSearch({ users }) { | ||
const [searchTerm, setSearchTerm] = useState(''); | ||
const [filtered, setFiltered] = useState(users); | ||
|
||
// A Standard Hook to mark things non-urgent | ||
const [isPending, startTransition] = useTransition(); | ||
|
||
const handleChange = ({ target: { value } }) => { | ||
// Set the search term on the textbox | ||
setSearchTerm(value); | ||
|
||
// Execute Non-Urgent Code | ||
startTransition(() => { | ||
// Filter the user list based on the search term | ||
setFiltered(users.filter((item) => item?.name.includes(value))); | ||
}); | ||
}; | ||
|
||
return ( | ||
<div className="user-container"> | ||
<h1>User Finder - Transition</h1> | ||
<div> | ||
{isPending ? ( | ||
<div>Loading...</div> | ||
) : ( | ||
<p>{users.length !== filtered.length ? `${filtered.length} matches` : null}</p> | ||
)} | ||
</div> | ||
|
||
<input placeholder="Type a name" type="text" value={searchTerm} onChange={handleChange} /> | ||
|
||
{isPending ? ( | ||
<div>Loading...</div> | ||
) : ( | ||
<div className="user-cards"> | ||
{filtered.length > 0 ? ( | ||
filtered.map((user) => ( | ||
<div class="card"> | ||
<div> | ||
<img alt={`Avatar image of ${user?.name}`} src={user?.avatar} /> | ||
</div> | ||
<div> | ||
<strong>{user?.name}</strong> | ||
</div> | ||
</div> | ||
)) | ||
) : ( | ||
<h4 className="nomatch">No Match Found...</h4> | ||
)} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* enter stlyes here */ | ||
.react-transition .modes { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
margin-bottom: 10px; | ||
} | ||
|
||
.react-transition .modes input[type='radio'] { | ||
margin-left: 10px; | ||
cursor: pointer; | ||
} | ||
|
||
.react-transition .modes label { | ||
font-size: 20px; | ||
margin-left: 2px; | ||
} | ||
|
||
.react-transition .user-container { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
} | ||
|
||
.react-transition .user-container input[type='text'] { | ||
margin: 10px; | ||
width: 80%; | ||
height: 30px; | ||
border-radius: 10px; | ||
margin-bottom: 30px; | ||
} | ||
|
||
.react-transition .user-cards { | ||
display: flex; | ||
flex-direction: row; | ||
flex-wrap: wrap; | ||
align-content: center; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
|
||
.react-transition .card { | ||
display: flex; | ||
flex-direction: column; | ||
margin: 10px; | ||
border-radius: 5px; | ||
border: 1px solid #ebebeb; | ||
padding: 10px; | ||
align-items: center; | ||
box-shadow: none; | ||
height: auto; | ||
width: auto; | ||
} | ||
|
||
.react-transition .card IMG { | ||
height: 128px; | ||
width: 128px; | ||
} | ||
|
||
.react-transition .nomatch { | ||
font-size: 60px; | ||
} |