feat(example): example done

This commit is contained in:
dqnid committed 2024-09-05 15:48:06 +02:00
1 parent 8f13dec0e4
commit 2c767eefe6
11 files changed
+193 -22

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@
"version": "1.0.0", "version": "1.0.0",
"scripts": { "scripts": {
"build": "rsbuild build", "build": "rsbuild build",
"dev": "rsbuild dev --open", "dev": "rsbuild dev",
"format": "prettier --write .", "format": "prettier --write .",
"lint": "eslint .", "lint": "eslint .",
"preview": "rsbuild preview" "preview": "rsbuild preview"
+43 -8
View File
@@ -1,8 +1,10 @@
body { body {
margin: 0; margin: 0;
color: #fff;
font-family: Inter, Avenir, Helvetica, Arial, sans-serif; font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
background-image: linear-gradient(to bottom, #020917, #101725);
--color-parent: #61a5c2;
--color-child: #89c2d9;
--color-grandchild: #a9d6e5;
} }
.content { .content {
@@ -12,15 +14,48 @@ body {
text-align: center; text-align: center;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center;
} }
.content h1 { .version__toggle {
font-size: 3.6rem; text-transform: capitalize;
font-weight: 700;
} }
.content p { .parent {
width: fit-content;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: var(--color-parent);
padding: 2rem;
border-radius: 8px;
}
.child {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 2rem;
border-radius: 8px;
background: var(--color-child);
position: relative;
}
.card__label {
padding: 0;
margin: 0;
position: absolute;
font-size: 1.2rem; font-size: 1.2rem;
font-weight: 400; line-height: 1.2rem;
opacity: 0.5; top: 0.4rem;
left: 0.4rem;
color: white;
}
.grandson {
position: relative;
padding: 1rem;
border-radius: 8px;
background: var(--color-grandchild);
} }
+18 -1
View File
@@ -1,10 +1,27 @@
import { useState } from 'react';
import './App.css'; import './App.css';
import { Parent } from './children-render/parent'; import { Parent } from './children-render/parent';
import { ParentFixed } from './children-render-fixed/parent-fixed';
import { FamilyContextProvider } from './children-render-fixed/family-context';
const App = () => { const App = () => {
const [version, setVersion] = useState<'normal' | 'fixed'>('normal');
return ( return (
<div className="content"> <div className="content">
<Parent /> <button
className="version__toggle"
onClick={() => setVersion(version === 'normal' ? 'fixed' : 'normal')}
>
Go to {version === 'normal' ? 'fixed' : 'normal'}
</button>
{version === 'normal' ? (
<Parent />
) : (
<FamilyContextProvider>
<ParentFixed />
</FamilyContextProvider>
)}
</div> </div>
); );
}; };
+12
View File
@@ -0,0 +1,12 @@
import { GrandsonFixed } from './grandson-fixed';
export const ChildFixed = () => {
console.log('__children render');
return (
<div className="child">
<h6 className="card__label">Child</h6>
<GrandsonFixed />
</div>
);
};
@@ -0,0 +1,13 @@
import { useFamily } from './family-context';
export const ContextInput = () => {
const { name, setName } = useFamily();
return (
<input
name="name"
type="text"
defaultValue={name}
onChange={(e) => setName(e.target.value)}
/>
);
};
@@ -0,0 +1,28 @@
import { createContext, useContext, useState } from 'react';
interface FamilyContextType {
name: string;
setName: (newName: string) => void;
}
const FamilyContext = createContext<FamilyContextType | undefined>(undefined);
const FamilyContextProvider: React.FC<React.PropsWithChildren> = ({
children,
}) => {
const [name, setName] = useState<string>('');
return (
<FamilyContext.Provider value={{ name, setName }}>
{children}
</FamilyContext.Provider>
);
};
const useFamily = () => {
const context = useContext(FamilyContext);
if (!context)
throw new Error('useFamily must be used within a FamilyContextProvider');
return context;
};
export { FamilyContextProvider, useFamily };
@@ -0,0 +1,14 @@
import { useFamily } from './family-context';
export const GrandsonFixed = () => {
console.log('__grandson render');
const { name } = useFamily();
return (
<div className="grandson">
<h6 className="card__label">Grandson</h6>
<p>Name: {name}</p>
</div>
);
};
@@ -0,0 +1,14 @@
import { ChildFixed } from './child-fixed';
import { ContextInput } from './context-input';
export const ParentFixed = () => {
console.log('__parent render');
return (
<div className="parent">
<h4>I'm the parent</h4>
<ContextInput />
<ChildFixed />
</div>
);
};
+19 -3
View File
@@ -1,13 +1,29 @@
import { useRef, useState } from 'react';
import { Grandson } from './grandson';
type ChildrenProps = { type ChildrenProps = {
counter: number; counter: number;
}; };
export const Children = (props: ChildrenProps) => { export const Children = (props: ChildrenProps) => {
console.log('__children render'); console.log('__children render');
const [myOwnState, setMyOwnState] = useState(0);
const myRef = useRef(0);
return ( return (
<div> <div className="child">
<h6>I'm its child</h6> <h6 className="card__label">Child</h6>
<p>My counter is {props.counter}</p> <p>My parent counter is {props.counter}</p>
<label>My own counter ir {myOwnState}</label>
<button onClick={() => setMyOwnState((prev) => prev + 1)}>
+1 own state
</button>
<label>My ref {myRef.current}</label>
<button onClick={() => (myRef.current = myRef.current + 1)}>
+1 own ref
</button>
<Grandson parentState={myOwnState} grandparentState={props.counter} />
</div> </div>
); );
}; };
+15
View File
@@ -0,0 +1,15 @@
type GrandsonProps = {
grandparentState: number;
parentState: number;
};
export const Grandson = (props: GrandsonProps) => {
console.log('__grandson render');
return (
<div className="grandson">
<h6 className="card__label">Grandson</h6>
<p>Parent state: {props.parentState}</p>
<p>Grandparent state: {props.grandparentState}</p>
</div>
);
};
+16 -9
View File
@@ -3,21 +3,28 @@ import { Children } from './children';
export const Parent = () => { export const Parent = () => {
console.log('__parent render'); console.log('__parent render');
const [counter, setCounter] = useState(0); const [ownState, setOwnState] = useState(0);
const [childrenCounter, setChildrenCounter] = useState(0); const [childrenPropState, setChildrenPropState] = useState(0);
const [name, setName] = useState<string>('');
return ( return (
<div> <div className="parent">
<h4>I'm the parent</h4> <h4>I'm the parent</h4>
<button onClick={() => setCounter((prev) => prev + 1)}> <input
Change own state! {counter} name="name"
type="text"
defaultValue={name}
onChange={(e) => setName(e.target.value)}
/>
<p>{name}</p>
<button onClick={() => setOwnState((prev) => prev + 1)}>
Change own state! {ownState}
</button> </button>
<button onClick={() => setChildrenCounter((prev) => prev + 1)}> <button onClick={() => setChildrenPropState((prev) => prev + 1)}>
Change children state! Change children state prop!
</button> </button>
<div> <div>
<h5>These are my children</h5> <Children counter={childrenPropState} />
<Children counter={childrenCounter} />
</div> </div>
</div> </div>
); );