feat(example): example done
This commit is contained in:
1 parent
8f13dec0e4
commit
2c767eefe6
11 files changed
+193
-22
No files matched your search
+1
-1
@@ -4,7 +4,7 @@
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"build": "rsbuild build",
|
||||
"dev": "rsbuild dev --open",
|
||||
"dev": "rsbuild dev",
|
||||
"format": "prettier --write .",
|
||||
"lint": "eslint .",
|
||||
"preview": "rsbuild preview"
|
||||
|
||||
+43
-8
@@ -1,8 +1,10 @@
|
||||
body {
|
||||
margin: 0;
|
||||
color: #fff;
|
||||
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 {
|
||||
@@ -12,15 +14,48 @@ body {
|
||||
text-align: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.content h1 {
|
||||
font-size: 3.6rem;
|
||||
font-weight: 700;
|
||||
.version__toggle {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.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-weight: 400;
|
||||
opacity: 0.5;
|
||||
line-height: 1.2rem;
|
||||
top: 0.4rem;
|
||||
left: 0.4rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.grandson {
|
||||
position: relative;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
background: var(--color-grandchild);
|
||||
}
|
||||
+18
-1
@@ -1,10 +1,27 @@
|
||||
import { useState } from 'react';
|
||||
import './App.css';
|
||||
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 [version, setVersion] = useState<'normal' | 'fixed'>('normal');
|
||||
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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 = {
|
||||
counter: number;
|
||||
};
|
||||
|
||||
export const Children = (props: ChildrenProps) => {
|
||||
console.log('__children render');
|
||||
const [myOwnState, setMyOwnState] = useState(0);
|
||||
const myRef = useRef(0);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h6>I'm its child</h6>
|
||||
<p>My counter is {props.counter}</p>
|
||||
<div className="child">
|
||||
<h6 className="card__label">Child</h6>
|
||||
<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>
|
||||
);
|
||||
};
|
||||
@@ -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 = () => {
|
||||
console.log('__parent render');
|
||||
const [counter, setCounter] = useState(0);
|
||||
const [childrenCounter, setChildrenCounter] = useState(0);
|
||||
const [ownState, setOwnState] = useState(0);
|
||||
const [childrenPropState, setChildrenPropState] = useState(0);
|
||||
const [name, setName] = useState<string>('');
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="parent">
|
||||
<h4>I'm the parent</h4>
|
||||
<button onClick={() => setCounter((prev) => prev + 1)}>
|
||||
Change own state! {counter}
|
||||
<input
|
||||
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 onClick={() => setChildrenCounter((prev) => prev + 1)}>
|
||||
Change children state!
|
||||
<button onClick={() => setChildrenPropState((prev) => prev + 1)}>
|
||||
Change children state prop!
|
||||
</button>
|
||||
<div>
|
||||
<h5>These are my children</h5>
|
||||
<Children counter={childrenCounter} />
|
||||
<Children counter={childrenPropState} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user