etc.
<Button primary>Clik me!</Button>
=== <Button primary={true}>Clik me!</Button>
<Button>Clik me!</Button>
~~= <Button primary={false}>Clik me!</Button>
It's actually undefined
, but treated the same as false
STYLING:
Introducing CSS Box Model
https://www.w3schools.com/css/css_boxmodel.asp
Classnames library:
https://www.npmjs.com/package/classnames
import className from "classnames";
// import classnames from "classnames"; // as in documentation, both imports are correct
const finalClassName = className("py-1.5", "border", "border-sky-600"); // "py-1.5 border border-sky-600"
const finalClassName = className({
"py-1.5": true, // object keys cannot have dashes and special signs within it, unless is is wrapped as string (" or ')
border: false,
"border-sky-600": 10, //any truthy value
"bg-sky-600": "",
}); // "py-1.5 border-sky-600"
const finalClassName = className("py-1.5", {
// always
border: resp_1, // the rest is conditional
"border-sky-600": resp_2,
"bg-sky-600": resp_1,
}); // "py-1.5 ...?"
const finalClassName = className("py-1.5", "border", "border-sky-600");
const finalClassName = className("py-1.5", "border", "border-sky-600");
console.log(finalClassName);
Tailwind and Tailwind-merge
https://tailwindcss.com/docs/
https://www.npmjs.com/package/tailwind-merge
Reusable "Presentation Components"
- Create a new component that shows a handful of JSX elements
- Make sure component accepts and uses
{children}
prop
- Allow extra
classNames
to be passed in and merge them - with className lib
- Take extra prop, pass them trough to root element - with
{...rest}
prop
check implementation here
React-icons
https://react-icons.github.io/react-icons/
npm install --save-exact [email protected]
Design proccess
What state
and event handlers
are there?
- List out what a user will do and changes they will see while using the app
- Categorize each step as
state
or event handler
- Group common steps. Remove duplicaes. Rewrite descriptions.
What name and type?
- Look at mockup (draft). Remove or simplify parts that aren't changing
- Replace remaning element with text descriptions
- Repeate #4 and #5 with a different variation
- Imagine you have to write a function that returns the text of steps #5 and #6. In addition to your component props - what other arguments would you need?
Where it is defined?
- Decide where each
event handler
and state
will be defined
Example (Accordian.js):
# What?
How accordion works: user clicks on section -> it should force the previously opened section to collapse and itself to expand. Actually this could be repeated for each section.
State - something changes on the screen (collapses, expands). Event handler - user perform some action (clicks).
State - sections are collapsing and the one clicked is expanding (1). Event handler - clicking on section header (1).
# Name and type
!! Avoid arrays / objects to be a type of piece of state !!
number, boolean, string should be fine
Text of headers does not change, text of 'body' also not change at all
Expanded - is a name of expanded section (1). Collapsed - name of sections that are collapsed (2+) [exp. coll. coll.]
[coll. exp. coll.], [coll. coll. exp.],
Imagine function, props and their types
function myFunction(items, /*???*/) {...}
myFunction(propsItems, /*???*/); // ['expanded', 'collapsed', 'collapsed']
myFunction(propsItems, /*???*/); // ['collapsed', 'expanded', 'collapsed']
myFunction(propsItems, /*???*/); // ['collapsed', 'collapsed', 'expanded']
/???/ - might be expendedIndex = 0, 1, 2; so the integer
# Where?
- does any other component has reasonable need to know the peace of state value? --> YES -> App.js | NO -> component.js
- event handler ususally is defined in the same component where the state it modifies (but might be used in another)
React does not print booleans, nulls, undefined
JS Boolean Expressions
||
returns the firts truthy value
&&
returns the first falsey value or the last truthy
React useState delays:
PROBLEM: React updates the piece of state but not immidatiely...
Batching is an optimization of React causing above issue but allowing to update few states in the same moment - the application works fast and smooth
How to see the issue?
Go to console:
$0.click(); // opens or closes the content
$0.click();
$0.click(); // the accordion does not come back to the initial state
It is only a problem when clicks become very quick one after another. Normal human user wouldn't be able to do this.
SOLUTION 1: Force React to update instantly
Truning batching off, but slowing app down...
SOLUTION 2: Access the most up to date value with Functional State Update
const [value, setValue] = useState(-1)
...
const handleClick = (newIdx) => {
setValue((current) => {
// use 'current' in the logic instead of 'value'
})
}
more in components/Accordion.js or Dropdown.js
Event handler in mapping function
const handleWithEvent = (event) => {...}
const handleWithProps = (passedOption) => {...}
consr rendered = data.map((option) => {
return <div> onClick={handleWithEvent} </div>
return <div> onClick={() => handleWithProps(option)} </div>
})
MASTERING DESIGN PROCESS - Dropdown:
& 2. Steps & Categorize
Clicks on dropdown - event
List of options appears - state
Clicks on option - event
List of options disappear - state
Clicked item appears shows in the box - state
Rewrite:
Events: clicks on dropdown, clicks on option (2)
States: dropdown expanded or collapsed, selected option in the box (2)
Look at mockup. Remove or simplify parts that aren't changing
Replace remaning element with text descriptions
Menu closed, no option selected
Menu opened, no option selected
Menu closed, 1st option is selected
Nothing to do with this simple component
Funtion + other arguments needed
STATES - name and type (and possible values):
// menu open or closed
myFunction(opts: list, isOpen: boolean) // true => menu opened, false => menu closed
// selected one of the option or null
myFunction(opts: list, selested: null | opts[n]) // nothing selected, {label: x, value, x1}
EVENTS - names for handlers:
handleSelect
, handleToggle
- Where?
optionSelected + handleSelect -> parent
menu opnened/closed + handleToggle -> Dropdown.js
- Create a new piece of state
- Create event handler watching on
onChange
event
- When
onChange
event fires, get the data from the input
- Update the state with that data
- Pass state to the input as the value prop
EXAMPLE + How react renders the above:
Look at:
This will be repeated in Dropdown component - chech
.
ad. 1. Create a new piece of state
in parent component (SearchBar)
and pass it to the child component (TextInput) as prop named "value".
Whenever data is passed to the "value prop" react forceably updates the text in text input
ad. 2. Create event handler
called "handleChange" in parent component
and pass it to child as onChange prop
when user pass anythign to the input, react fires the onChange and thus hadleChange function with new data
ad. 4. Update the state with that data
inside handleChange function,
because the state was updated the parent (SearchBar) is going to rerender itself and pass new state to the value prop of child (TextInput)
...react foceably updates the text...
Comminity Convention with Prop Names
Refers only to child component, not the parent one - there the names (piece of state and event handler) could be whatever I choose
form control
component - any kind of component where user provide some input value (text, text area, text input, dropdown, checkbox etc.)
value
- name of the prop where the current value is stored
onChange
- name of the prop called when value changed
Dropdown bug
Clicking on second dropdown (or anywhere else) should close the first dropdown - look here
JS Solution: Document-wide event listiner
const handleClick = (event) => {
console.log(event.target);
};
document.addEventListener("click", handleClick);
Event capturing / bubbling
Whenever user interact with page (clik, drag, drop etc..) browser searches for event handlers corresponding to user action. This searching is divided into 3 phases:
Capture Phase
--> Target Phase
--> Bubble Phase
Example application:
<body>
<div>
<button>Click me!</button>
</div>
</body>
User clicks on button, so the browser starts searching the event handler.
Ad. Capture Phase
Browser looks at element cliked