feat(example): example done
This commit is contained in:
1 parent
8f13dec0e4
commit
2c767eefe6
11 files changed
+192
-21
No files matched your search
+1
-1
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
+17
@@ -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">
|
||||||
|
<button
|
||||||
|
className="version__toggle"
|
||||||
|
onClick={() => setVersion(version === 'normal' ? 'fixed' : 'normal')}
|
||||||
|
>
|
||||||
|
Go to {version === 'normal' ? 'fixed' : 'normal'}
|
||||||
|
</button>
|
||||||
|
{version === 'normal' ? (
|
||||||
<Parent />
|
<Parent />
|
||||||
|
) : (
|
||||||
|
<FamilyContextProvider>
|
||||||
|
<ParentFixed />
|
||||||
|
</FamilyContextProvider>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -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>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user